netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [iptables-nftables - RFC v2 PATCH  00/17] Xtables extensions: full support (pure nft or compat layer)
@ 2013-07-25 17:16 Tomasz Bursztyka
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 01/17] nft: Remove useless function Tomasz Bursztyka
                   ` (16 more replies)
  0 siblings, 17 replies; 18+ messages in thread
From: Tomasz Bursztyka @ 2013-07-25 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

Hi,

Ok I won't repeat the long text about this RFC here again.
For more information, look at mail thread: "[iptables-nftables - RFC PATCH  00/15] Xtables extensions: full support (pure nft or compat layer)"

I applied the basic changes I told.

Note: this version still requires to be built with --enable-static. See patch 9.

Thanks,


Tomasz Bursztyka (17):
  nft: Remove useless function
  xtables: Add support for injecting xtables target into nft rule
  xtables: add support for injecting xtables matches into nft rule
  nft: Add nft expressions translation engine as a library
  nft: Integrate nft translator engine in current core
  nft: Manage xtables target parsing through translation tree
  nft: Manage xtables matches through nft translation tree
  nft: Add support for xtables extensions callback to change cs
  xtables: Add support for registering nft translation function for
    target
  xtables: Add support for registering nft translation function for
    match
  nft: Register all relevant xtables extensions into translation tree
  nft: Refactor firewall printing so it reuses already parsed cs struct
  nft: Refactor rule deletion so it compares both cs structure
  xtables: nft: Complete refactoring on how rules are saved
  xtables: Support pure nft expressions for DNAT extension
  nft: Add a function to reset the counters of an existing rule
  xtables: Support -Z options for a given rule number

 Makefile.am                       |   3 +
 configure.ac                      |   8 +
 extensions/GNUmakefile.in         |   1 +
 extensions/libipt_DNAT.c          | 221 +++++++++
 include/nft-translator.h          |  81 ++++
 include/xtables.h                 |  13 +
 iptables/Makefile.am              |   3 +-
 iptables/nft-ipv4.c               | 125 ++---
 iptables/nft-ipv6.c               |  81 ++--
 iptables/nft-shared.c             |  72 ++-
 iptables/nft-shared.h             |  23 +-
 iptables/nft-xt-ext.c             | 178 ++++++++
 iptables/nft-xt-ext.h             |  14 +
 iptables/nft.c                    | 934 +++++++++++++-------------------------
 iptables/nft.h                    |   9 +-
 iptables/xtables-events.c         |  21 +-
 iptables/xtables.c                |  15 +-
 libnfttrans/.nft-translator.c.swp | Bin 0 -> 28672 bytes
 libnfttrans/Makefile.am           |  28 ++
 libnfttrans/libnfttrans.pc        |  11 +
 libnfttrans/libnfttrans.pc.in     |  11 +
 libnfttrans/nft-translator.c      | 571 +++++++++++++++++++++++
 22 files changed, 1637 insertions(+), 786 deletions(-)
 create mode 100644 include/nft-translator.h
 create mode 100644 iptables/nft-xt-ext.c
 create mode 100644 iptables/nft-xt-ext.h
 create mode 100644 libnfttrans/.nft-translator.c.swp
 create mode 100644 libnfttrans/Makefile.am
 create mode 100644 libnfttrans/libnfttrans.pc
 create mode 100644 libnfttrans/libnfttrans.pc.in
 create mode 100644 libnfttrans/nft-translator.c

-- 
1.8.3.2


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

* [iptables-nftables - RFC v2 PATCH  01/17] nft: Remove useless function
  2013-07-25 17:16 [iptables-nftables - RFC v2 PATCH 00/17] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
@ 2013-07-25 17:16 ` Tomasz Bursztyka
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 02/17] xtables: Add support for injecting xtables target into nft rule Tomasz Bursztyka
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Tomasz Bursztyka @ 2013-07-25 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 iptables/nft.c | 27 ---------------------------
 1 file changed, 27 deletions(-)

diff --git a/iptables/nft.c b/iptables/nft.c
index 9a857b9..a943069 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -1676,33 +1676,6 @@ next:
 	return 0;
 }
 
-static inline int
-match_different(const struct xt_entry_match *a,
-		const unsigned char *a_elems,
-		const unsigned char *b_elems,
-		unsigned char **maskptr)
-{
-	const struct xt_entry_match *b;
-	unsigned int i;
-
-	/* Offset of b is the same as a. */
-	b = (void *)b_elems + ((unsigned char *)a - a_elems);
-
-	if (a->u.match_size != b->u.match_size)
-		return 1;
-
-	if (strcmp(a->u.user.name, b->u.user.name) != 0)
-		return 1;
-
-	*maskptr += XT_ALIGN(sizeof(*a));
-
-	for (i = 0; i < a->u.match_size - XT_ALIGN(sizeof(*a)); i++)
-		if (((a->data[i] ^ b->data[i]) & (*maskptr)[i]) != 0)
-			return 1;
-	*maskptr += i;
-	return 0;
-}
-
 static void
 nft_parse_meta(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter,
 	       int family, struct iptables_command_state *cs)
-- 
1.8.3.2


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

* [iptables-nftables - RFC v2 PATCH  02/17] xtables: Add support for injecting xtables target into nft rule
  2013-07-25 17:16 [iptables-nftables - RFC v2 PATCH 00/17] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 01/17] nft: Remove useless function Tomasz Bursztyka
@ 2013-07-25 17:16 ` Tomasz Bursztyka
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 03/17] xtables: add support for injecting xtables matches " Tomasz Bursztyka
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Tomasz Bursztyka @ 2013-07-25 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

This bring the support for xtables target extentions to be translated to
pure nft expression list in the given rule.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 configure.ac              |  7 +++++++
 extensions/GNUmakefile.in |  1 +
 include/xtables.h         |  5 +++++
 iptables/nft.c            | 20 ++++++++++++--------
 4 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/configure.ac b/configure.ac
index 1c713e8..68f661c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -119,6 +119,13 @@ PKG_CHECK_MODULES([libnftables], [libnftables >= 1.0],
 	[nftables=1], [nftables=0])
 AM_CONDITIONAL([HAVE_LIBNFTABLES], [test "$nftables" = 1])
 
+if test "$nftables" = 1; then
+	EXTENSION_NFT_LDFLAGS="${libmnl_LIBS} ${libnftables_LIBS}";
+else
+	EXTENSION_NFT_LDFLAGS="";
+fi;
+AC_SUBST(EXTENSION_NFT_LDFLAGS)
+
 AM_PROG_LEX
 AC_PROG_YACC
 
diff --git a/extensions/GNUmakefile.in b/extensions/GNUmakefile.in
index 14e7c57..da2f38b 100644
--- a/extensions/GNUmakefile.in
+++ b/extensions/GNUmakefile.in
@@ -16,6 +16,7 @@ CCLD               = ${CC}
 CFLAGS             = @CFLAGS@
 CPPFLAGS           = @CPPFLAGS@
 LDFLAGS            = @LDFLAGS@
+@ENABLE_NFTABLES_TRUE@ LDFLAGS += @EXTENSION_NFT_LDFLAGS@
 regular_CFLAGS     = @regular_CFLAGS@
 regular_CPPFLAGS   = @regular_CPPFLAGS@
 kinclude_CPPFLAGS  = @kinclude_CPPFLAGS@
diff --git a/include/xtables.h b/include/xtables.h
index d4a4395..4d8874c 100644
--- a/include/xtables.h
+++ b/include/xtables.h
@@ -18,6 +18,8 @@
 #include <linux/netfilter.h>
 #include <linux/netfilter/x_tables.h>
 
+#include <libnftables/rule.h>
+
 #ifndef IPPROTO_SCTP
 #define IPPROTO_SCTP 132
 #endif
@@ -346,6 +348,9 @@ struct xtables_target
 	void (*x6_fcheck)(struct xt_fcheck_call *);
 	const struct xt_option_entry *x6_options;
 
+	/* NFT related */
+	int (*to_nft)(struct nft_rule *, struct xt_entry_target *);
+
 	size_t udata_size;
 
 	/* Ignore these men behind the curtain: */
diff --git a/iptables/nft.c b/iptables/nft.c
index a943069..d178f19 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -609,17 +609,21 @@ static int __add_target(struct nft_rule_expr *e, struct xt_entry_target *t)
 	return 0;
 }
 
-static int add_target(struct nft_rule *r, struct xt_entry_target *t)
+static int add_target(struct nft_rule *r, struct xtables_target *target)
 {
-	struct nft_rule_expr *expr;
 	int ret;
 
-	expr = nft_rule_expr_alloc("target");
-	if (expr == NULL)
-		return -ENOMEM;
+	if (target->to_nft == NULL) {
+		struct nft_rule_expr *expr;
 
-	ret = __add_target(expr, t);
-	nft_rule_add_expr(r, expr);
+		expr = nft_rule_expr_alloc("target");
+		if (expr == NULL)
+			return -ENOMEM;
+
+		ret = __add_target(expr, target->t);
+		nft_rule_add_expr(r, expr);
+	} else
+		ret = target->to_nft(r, target->t);
 
 	return ret;
 }
@@ -728,7 +732,7 @@ nft_rule_new(struct nft_handle *h, const char *chain, const char *table,
 		else if (strcmp(cs->jumpto, XTC_LABEL_RETURN) == 0)
 			ret = add_verdict(r, NFT_RETURN);
 		else
-			ret = add_target(r, cs->target->t);
+			ret = add_target(r, cs->target);
 	} else if (strlen(cs->jumpto) > 0) {
 		/* Not standard, then it's a go / jump to chain */
 		if (ip_flags & IPT_F_GOTO)
-- 
1.8.3.2


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

* [iptables-nftables - RFC v2 PATCH  03/17] xtables: add support for injecting xtables matches into nft rule
  2013-07-25 17:16 [iptables-nftables - RFC v2 PATCH 00/17] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 01/17] nft: Remove useless function Tomasz Bursztyka
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 02/17] xtables: Add support for injecting xtables target into nft rule Tomasz Bursztyka
@ 2013-07-25 17:16 ` Tomasz Bursztyka
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 04/17] nft: Add nft expressions translation engine as a library Tomasz Bursztyka
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Tomasz Bursztyka @ 2013-07-25 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

This bring the support for xtables matches extentions to be translated to
pure nft expression list in the given rule.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 include/xtables.h |  3 +++
 iptables/nft.c    | 20 ++++++++++++--------
 2 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/include/xtables.h b/include/xtables.h
index 4d8874c..5bd8a59 100644
--- a/include/xtables.h
+++ b/include/xtables.h
@@ -271,6 +271,9 @@ struct xtables_match
 	void (*x6_fcheck)(struct xt_fcheck_call *);
 	const struct xt_option_entry *x6_options;
 
+	/* NFT related */
+	int (*to_nft)(struct nft_rule *r, struct xt_entry_match *);
+
 	/* Size of per-extension instance extra "global" scratch space */
 	size_t udata_size;
 
diff --git a/iptables/nft.c b/iptables/nft.c
index d178f19..685a203 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -573,17 +573,21 @@ static int __add_match(struct nft_rule_expr *e, struct xt_entry_match *m)
 	return 0;
 }
 
-static int add_match(struct nft_rule *r, struct xt_entry_match *m)
+static int add_match(struct nft_rule *r, struct xtables_match *match)
 {
-	struct nft_rule_expr *expr;
 	int ret;
 
-	expr = nft_rule_expr_alloc("match");
-	if (expr == NULL)
-		return -ENOMEM;
+	if (match->to_nft == NULL) {
+		struct nft_rule_expr *expr;
 
-	ret = __add_match(expr, m);
-	nft_rule_add_expr(r, expr);
+		expr = nft_rule_expr_alloc("match");
+		if (expr == NULL)
+			return -ENOMEM;
+
+		ret = __add_match(expr, match->m);
+		nft_rule_add_expr(r, expr);
+	} else
+		ret = match->to_nft(r, match->m);
 
 	return ret;
 }
@@ -712,7 +716,7 @@ nft_rule_new(struct nft_handle *h, const char *chain, const char *table,
 	ip_flags = h->ops->add(r, cs);
 
 	for (matchp = cs->matches; matchp; matchp = matchp->next) {
-		if (add_match(r, matchp->match->m) < 0)
+		if (add_match(r, matchp->match) < 0)
 			goto err;
 	}
 
-- 
1.8.3.2


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

* [iptables-nftables - RFC v2 PATCH  04/17] nft: Add nft expressions translation engine as a library
  2013-07-25 17:16 [iptables-nftables - RFC v2 PATCH 00/17] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
                   ` (2 preceding siblings ...)
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 03/17] xtables: add support for injecting xtables matches " Tomasz Bursztyka
@ 2013-07-25 17:16 ` Tomasz Bursztyka
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 05/17] nft: Integrate nft translator engine in current core Tomasz Bursztyka
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Tomasz Bursztyka @ 2013-07-25 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

libnfttrans is a generic translation engine from nft expressions to
registered "complex instructions". It works on a simple tree based
pattern matching algorithm.

Idea is to be able to register any kind of expressions suit (or pattern)
linked to a parsing function representing the "complex instruction".
Then, being able to go through the whole expression list of a rule and
retrieving the original complex instructions suit.

This will fix at once the parsing of a rule, taking into account
current compatilbe layer for extentions but also their pure nft version.
As soon as an expression will implement its method to express itself as
pur nft expression the change will be totally transparent.

Once applied on xtables (iptables over nftables), this will allow to
retrieve the exact iptables_command_state structure for instance.
However, such engine is generic enough to be reused in any other tool,
like future arptables and ebtables compatible tool over nftables.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 Makefile.am                       |   3 +
 configure.ac                      |   1 +
 include/nft-translator.h          |  81 ++++++
 libnfttrans/.nft-translator.c.swp | Bin 0 -> 28672 bytes
 libnfttrans/Makefile.am           |  28 ++
 libnfttrans/libnfttrans.pc        |  11 +
 libnfttrans/libnfttrans.pc.in     |  11 +
 libnfttrans/nft-translator.c      | 571 ++++++++++++++++++++++++++++++++++++++
 8 files changed, 706 insertions(+)
 create mode 100644 include/nft-translator.h
 create mode 100644 libnfttrans/.nft-translator.c.swp
 create mode 100644 libnfttrans/Makefile.am
 create mode 100644 libnfttrans/libnfttrans.pc
 create mode 100644 libnfttrans/libnfttrans.pc.in
 create mode 100644 libnfttrans/nft-translator.c

diff --git a/Makefile.am b/Makefile.am
index c38d360..fa762d4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,6 +4,9 @@ ACLOCAL_AMFLAGS  = -I m4
 AUTOMAKE_OPTIONS = foreign subdir-objects
 
 SUBDIRS          = libiptc libxtables
+if ENABLE_NFTABLES
+SUBDIRS		+= libnfttrans
+endif
 if ENABLE_DEVEL
 SUBDIRS         += include
 endif
diff --git a/configure.ac b/configure.ac
index 68f661c..4ca6f65 100644
--- a/configure.ac
+++ b/configure.ac
@@ -207,6 +207,7 @@ AC_CONFIG_FILES([Makefile extensions/GNUmakefile include/Makefile
 	libiptc/Makefile libiptc/libiptc.pc
 	libiptc/libip4tc.pc libiptc/libip6tc.pc
 	libxtables/Makefile utils/Makefile
+	libnfttrans/Makefile libnfttrans/libnfttrans.pc
 	include/xtables-version.h include/iptables/internal.h])
 AC_OUTPUT
 
diff --git a/include/nft-translator.h b/include/nft-translator.h
new file mode 100644
index 0000000..318f248
--- /dev/null
+++ b/include/nft-translator.h
@@ -0,0 +1,81 @@
+/*
+ * (C) 2013 by Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef _NFT_TRANSLATOR_H
+#define _NFT_TRANSLATOR_H
+
+#include <stdint.h>
+#include <libnftables/rule.h>
+#include <libnftables/expr.h>
+
+enum nft_instruction {
+	NFT_INSTRUCTION_BITWISE   = 0,
+	NFT_INSTRUCTION_BYTEORDER = 1,
+	NFT_INSTRUCTION_CMP       = 2,
+	NFT_INSTRUCTION_COUNTER   = 3,
+	NFT_INSTRUCTION_CT        = 4,
+	NFT_INSTRUCTION_EXTHDR    = 5,
+	NFT_INSTRUCTION_IMMEDIATE = 6,
+	NFT_INSTRUCTION_LIMIT     = 7,
+	NFT_INSTRUCTION_LOG       = 8,
+	NFT_INSTRUCTION_LOOKUP    = 9,
+	NFT_INSTRUCTION_MATCH     = 10,
+	NFT_INSTRUCTION_META      = 11,
+	NFT_INSTRUCTION_NAT       = 12,
+	NFT_INSTRUCTION_PAYLOAD   = 13,
+	NFT_INSTRUCTION_REJECT    = 14,
+	NFT_INSTRUCTION_TARGET    = 15,
+	NFT_INSTRUCTION_MAX       = 16,
+};
+
+struct nft_trans_instruction_tree;
+struct nft_trans_rule_context;
+struct nft_trans_instruction_context;
+
+typedef int (*nft_trans_parse_callback_f)(const char *ident,
+					  void *data,
+					  void *user_data);
+
+typedef int
+(*nft_trans_parse_instruction_f)(struct nft_trans_rule_context *rule_ctx,
+				 struct nft_trans_instruction_context *first,
+				 struct nft_trans_instruction_context *last,
+				 nft_trans_parse_callback_f user_cb,
+				 void *user_data);
+
+struct nft_trans_instruction {
+	enum nft_instruction *instructions;
+	nft_trans_parse_instruction_f function;
+};
+
+struct nft_trans_instruction_tree *nft_trans_instruction_tree_new(void);
+
+void
+nft_trans_instruction_tree_destroy(struct nft_trans_instruction_tree *tree);
+
+int nft_trans_add_instruction(struct nft_trans_instruction_tree *tree,
+			      struct nft_trans_instruction *ipt_i);
+
+int
+nft_trans_rule_translate_to_instructions(struct nft_trans_instruction_tree *tree,
+					 struct nft_rule *rule,
+					 nft_trans_parse_callback_f user_cb,
+					 void *user_data);
+
+struct nft_trans_instruction_context *
+nft_trans_instruction_context_get_next(struct nft_trans_instruction_context *i_ctx);
+
+struct nft_rule_expr *
+nft_trans_instruction_context_get_expr(struct nft_trans_instruction_context *i_ctx);
+
+struct nft_rule_expr *
+nft_trans_instruction_context_get_register(struct nft_trans_instruction_context *i_ctx,
+					   int reg);
+
+#endif /* _NFT_TRANSLATOR_H */
diff --git a/libnfttrans/.nft-translator.c.swp b/libnfttrans/.nft-translator.c.swp
new file mode 100644
index 0000000000000000000000000000000000000000..0f94354ee52aee9374279892aa9b04fe93da0dcd
GIT binary patch
literal 28672
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
EFV{Li$N&HU

literal 0
HcmV?d00001

diff --git a/libnfttrans/Makefile.am b/libnfttrans/Makefile.am
new file mode 100644
index 0000000..5befb63
--- /dev/null
+++ b/libnfttrans/Makefile.am
@@ -0,0 +1,28 @@
+# -*- Makefile -*-
+if ENABLE_NFTABLES
+if HAVE_LIBMNL
+if HAVE_LIBNFTABLES
+
+AM_CFLAGS   = ${regular_CFLAGS}
+AM_CPPFLAGS = ${regular_CPPFLAGS}  -I${top_builddir}/include \
+		-I${top_srcdir}/include  -I./ ${kinclude_CPPFLAGS}
+
+lib_LTLIBRARIES       = libnfttrans.la
+libnfttrans_la_SOURCES = nft-translator.c
+libnfttrans_la_LDFLAGS =
+libnfttrans_la_LIBADD  =
+if ENABLE_STATIC
+# With --enable-static, shipped extensions are linked into the main executable,
+# so we need all the LIBADDs here too
+libnfttrans_la_LIBADD += -lm
+endif
+if ENABLE_SHARED
+libnfttrans_la_CFLAGS  = ${AM_CFLAGS}
+libnfttrans_la_LIBADD += -ldl
+else
+libnfttrans_la_CFLAGS  = ${AM_CFLAGS} -DNO_SHARED_LIBS=1
+endif
+
+endif # HAVE_LIBNFTABLES
+endif # HAVE_LIBMNL
+endif # ENABLE_NFTABLES
diff --git a/libnfttrans/libnfttrans.pc b/libnfttrans/libnfttrans.pc
new file mode 100644
index 0000000..fe0b4c0
--- /dev/null
+++ b/libnfttrans/libnfttrans.pc
@@ -0,0 +1,11 @@
+
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name:		libnfttrans
+Description:	Small engine to translate nft expressions list into more complex registered subset
+Version:	1.4.19.1
+Libs:		-L${libdir} -lnfttrans
+Cflags:		-I${includedir}
diff --git a/libnfttrans/libnfttrans.pc.in b/libnfttrans/libnfttrans.pc.in
new file mode 100644
index 0000000..f3363de
--- /dev/null
+++ b/libnfttrans/libnfttrans.pc.in
@@ -0,0 +1,11 @@
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name:		libnfttrans
+Description:	Small engine to translate nft expressions list into more complex registered subset
+Version:	@PACKAGE_VERSION@
+Libs:		-L${libdir} -lnfttrans
+Cflags:		-I${includedir}
diff --git a/libnfttrans/nft-translator.c b/libnfttrans/nft-translator.c
new file mode 100644
index 0000000..12bd7e5
--- /dev/null
+++ b/libnfttrans/nft-translator.c
@@ -0,0 +1,571 @@
+/*
+ * (C) 2013 by Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <linux/netfilter/nf_tables.h>
+
+#include <nft-translator.h>
+
+static const char *nft_instruction_name[NFT_INSTRUCTION_MAX] = {
+	"bitwise",
+	"byteorder",
+	"cmp",
+	"counter",
+	"ct",
+	"exthdr",
+	"immediate",
+	"limit",
+	"log",
+	"lookup",
+	"match",
+	"meta",
+	"nat",
+	"payload",
+	"reject",
+	"target",
+};
+
+typedef void (*free_function_f)(void *);
+
+struct s_list {
+	void *data;
+	struct s_list *next;
+};
+
+struct nft_trans_instruction_node {
+	struct s_list *functions;
+	struct nft_trans_instruction_node *nodes[NFT_INSTRUCTION_MAX];
+};
+
+struct nft_trans_instruction_tree {
+	struct s_list *nodes;
+	struct nft_trans_instruction_node *root;
+};
+
+struct nft_trans_register_context {
+	struct nft_rule_expr *reg[NFT_REG_MAX];
+};
+
+struct nft_trans_instruction_context {
+	struct nft_trans_instruction_context *next;
+
+	struct nft_rule_expr *current_expr;
+	enum nft_instruction instruction;
+	struct nft_trans_register_context *registers;
+};
+
+struct nft_trans_rule_context {
+	struct nft_trans_instruction_context *instr_contexts;
+};
+
+struct nft_trans_found_instruction {
+	const struct s_list *functions;
+	struct nft_trans_instruction_context *position;
+};
+
+static enum nft_instruction str2nft_intruction(const char *name)
+{
+	enum nft_instruction i;
+
+	for (i = 0; i < NFT_INSTRUCTION_MAX; i++) {
+		 if (strncmp(nft_instruction_name[i], name,
+					strlen(nft_instruction_name[i])) == 0)
+			 return i;
+	}
+
+	return NFT_INSTRUCTION_MAX;
+}
+
+static struct s_list *s_list_prepend(struct s_list *list, void *data)
+{
+	struct s_list *n_list;
+
+	n_list = calloc(1, sizeof(struct s_list));
+	if (n_list == NULL)
+		return list;
+
+	n_list->data = data;
+	n_list->next = list;
+
+	return n_list;
+}
+
+static void s_list_free(struct s_list *list, int data_too,
+			 free_function_f _free)
+{
+	struct s_list *previous = NULL;
+
+	for (; list != NULL; list = list->next) {
+		if (previous != NULL) {
+			if (previous->data != NULL && data_too != 0) {
+				if (_free != NULL)
+					_free(previous->data);
+				else
+					free(previous->data);
+			}
+
+			free(previous);
+		}
+
+		previous = list;
+	}
+
+	if (previous != NULL) {
+		if (previous->data != NULL && data_too != 0) {
+			if (_free != NULL)
+				_free(previous->data);
+			else
+				free(previous->data);
+		}
+
+		free(previous);
+	}
+}
+
+struct nft_trans_instruction_tree *nft_trans_instruction_tree_new(void)
+{
+	struct nft_trans_instruction_tree *tree;
+
+	tree = calloc(1, sizeof(struct nft_trans_instruction_tree));
+	if (tree != NULL) {
+		tree->root = calloc(1, sizeof(struct nft_trans_instruction_node));
+		if (tree->root == NULL)
+			goto error;
+
+		tree->nodes = s_list_prepend(tree->nodes, tree->root);
+		if (tree->nodes == NULL)
+			goto error;
+	}
+
+	return tree;
+
+error:
+	free(tree);
+	return NULL;
+}
+
+static void _free_nft_trans_instruction_node(void *data)
+{
+	struct nft_trans_instruction_node *node = data;
+
+	if (node == NULL)
+		return;
+
+	s_list_free(node->functions, 0, NULL);
+	free(node);
+}
+
+void
+nft_trans_instruction_tree_destroy(struct nft_trans_instruction_tree *tree)
+{
+	if (tree == NULL)
+		return;
+
+	s_list_free(tree->nodes, 1, _free_nft_trans_instruction_node);
+	free(tree);
+}
+
+int nft_trans_add_instruction(struct nft_trans_instruction_tree *tree,
+			      struct nft_trans_instruction *ipt_i)
+{
+	struct nft_trans_instruction_node *node;
+	enum nft_instruction *instr;
+
+	if (tree == NULL)
+		return -EINVAL;
+
+	node = tree->root;
+	for (instr = ipt_i->instructions;
+				*instr < NFT_INSTRUCTION_MAX; instr++) {
+		if (node->nodes[*instr] == NULL) {
+			node->nodes[*instr] = calloc(1,
+					sizeof(struct nft_trans_instruction_node));
+			if (node->nodes[*instr] == NULL)
+				return -ENOMEM;
+		}
+
+		node = node->nodes[*instr];
+		tree->nodes = s_list_prepend(tree->nodes, node);
+	}
+
+	node->functions = s_list_prepend(node->functions, ipt_i->function);
+
+	return 0;
+}
+
+static void
+free_nft_trans_instruction_context(struct nft_trans_instruction_context *i_ctx)
+{
+	if (i_ctx == NULL)
+		return;
+
+	free(i_ctx->registers);
+	free(i_ctx);
+}
+
+static void
+destroy_nft_trans_rule_context(struct nft_trans_rule_context *rule_ctx)
+{
+	if (rule_ctx == NULL)
+		return;
+
+	if (rule_ctx->instr_contexts != NULL) {
+		struct nft_trans_instruction_context *i_ctx, *prev = NULL;
+
+		for (i_ctx = rule_ctx->instr_contexts;
+					i_ctx != NULL; i_ctx = i_ctx->next) {
+			free_nft_trans_instruction_context(prev);
+			prev = i_ctx;
+		}
+
+		free_nft_trans_instruction_context(prev);
+	}
+
+	free(rule_ctx);
+}
+
+static void
+update_register_from_bitwise(struct nft_rule_expr *expr,
+			     struct nft_trans_register_context *registers)
+{
+	if (nft_rule_expr_is_set(expr, NFT_EXPR_BITWISE_DREG))
+		registers->reg[nft_rule_expr_get_u32(expr,
+						NFT_EXPR_BITWISE_DREG)] = expr;
+}
+
+static void
+update_register_from_byteorder(struct nft_rule_expr *expr,
+			       struct nft_trans_register_context *registers)
+{
+	if (nft_rule_expr_is_set(expr, NFT_EXPR_BYTEORDER_DREG))
+		registers->reg[nft_rule_expr_get_u32(expr,
+					NFT_EXPR_BYTEORDER_DREG)] = expr;
+}
+
+static void
+update_register_from_ct(struct nft_rule_expr *expr,
+			struct nft_trans_register_context *registers)
+{
+	if (nft_rule_expr_is_set(expr, NFT_EXPR_CT_DREG))
+		registers->reg[nft_rule_expr_get_u32(expr,
+						NFT_EXPR_CT_DREG)] = expr;
+}
+
+static void
+update_register_from_exthdr(struct nft_rule_expr *expr,
+			    struct nft_trans_register_context *registers)
+{
+	if (nft_rule_expr_is_set(expr, NFT_EXPR_EXTHDR_DREG))
+		registers->reg[nft_rule_expr_get_u32(expr,
+						NFT_EXPR_EXTHDR_DREG)] = expr;
+}
+
+static void
+update_register_from_immediate(struct nft_rule_expr *expr,
+			       struct nft_trans_register_context *registers)
+{
+	if (nft_rule_expr_is_set(expr, NFT_EXPR_IMM_DREG))
+		registers->reg[nft_rule_expr_get_u32(expr,
+						NFT_EXPR_IMM_DREG)] = expr;
+}
+
+static void
+update_register_from_lookup(struct nft_rule_expr *expr,
+			    struct nft_trans_register_context *registers)
+{
+	if (nft_rule_expr_is_set(expr, NFT_EXPR_LOOKUP_DREG))
+		registers->reg[nft_rule_expr_get_u32(expr,
+						NFT_EXPR_LOOKUP_DREG)] = expr;
+}
+
+static void
+update_register_from_meta(struct nft_rule_expr *expr,
+			  struct nft_trans_register_context *registers)
+{
+	if (nft_rule_expr_is_set(expr, NFT_EXPR_META_DREG))
+		registers->reg[nft_rule_expr_get_u32(expr,
+						NFT_EXPR_META_DREG)] = expr;
+}
+
+static void
+update_register_from_payload(struct nft_rule_expr *expr,
+			     struct nft_trans_register_context *registers)
+{
+	if (nft_rule_expr_is_set(expr, NFT_EXPR_PAYLOAD_DREG))
+		registers->reg[nft_rule_expr_get_u32(expr,
+						NFT_EXPR_PAYLOAD_DREG)] = expr;
+}
+
+static struct nft_trans_register_context *
+update_registers(enum nft_instruction instruction, struct nft_rule_expr *expr,
+		 struct nft_trans_register_context *registers)
+{
+	struct nft_trans_register_context *new_registers;
+
+	new_registers = calloc(1, sizeof(struct nft_trans_register_context));
+	if (new_registers == NULL)
+		return NULL;
+
+	memcpy(new_registers, registers, sizeof(struct nft_trans_register_context));
+
+	switch (instruction) {
+	case NFT_INSTRUCTION_BITWISE:
+		update_register_from_bitwise(expr, new_registers);
+		break;
+	case NFT_INSTRUCTION_BYTEORDER:
+		update_register_from_byteorder(expr, new_registers);
+		break;
+	case NFT_INSTRUCTION_CMP:
+	case NFT_INSTRUCTION_COUNTER:
+		break;
+	case NFT_INSTRUCTION_CT:
+		update_register_from_ct(expr, new_registers);
+		break;
+	case NFT_INSTRUCTION_EXTHDR:
+		update_register_from_exthdr(expr, new_registers);
+		break;
+	case NFT_INSTRUCTION_IMMEDIATE:
+		update_register_from_immediate(expr, new_registers);
+		break;
+	case NFT_INSTRUCTION_LIMIT:
+	case NFT_INSTRUCTION_LOG:
+		break;
+	case NFT_INSTRUCTION_LOOKUP:
+		update_register_from_lookup(expr, new_registers);
+		break;
+	case NFT_INSTRUCTION_MATCH:
+		break;
+	case NFT_INSTRUCTION_META:
+		update_register_from_meta(expr, new_registers);
+		break;
+	case NFT_INSTRUCTION_NAT:
+		break;
+	case NFT_INSTRUCTION_PAYLOAD:
+		update_register_from_payload(expr, new_registers);
+		break;
+	case NFT_INSTRUCTION_REJECT:
+	case NFT_INSTRUCTION_TARGET:
+		break;
+	case NFT_INSTRUCTION_MAX:
+		return NULL;
+	};
+
+	return new_registers;
+}
+
+static struct nft_trans_rule_context *
+generate_nft_trans_rule_context(struct nft_rule *rule)
+{
+	struct nft_trans_instruction_context *cur_ctx = NULL;
+	struct nft_trans_register_context *cur_regs = NULL;
+	struct nft_trans_rule_context *rule_ctx;
+	struct nft_rule_expr_iter *iter;
+	struct nft_rule_expr *expr;
+
+	rule_ctx = calloc(1, sizeof(struct nft_trans_rule_context));
+	if (rule_ctx == NULL)
+		return NULL;
+
+	iter = nft_rule_expr_iter_create(rule);
+	if (iter == NULL)
+		goto error;
+
+	cur_regs = calloc(1, sizeof(struct nft_trans_register_context));
+	if (cur_regs == NULL)
+		goto error;
+
+	expr = nft_rule_expr_iter_next(iter);
+	while (expr != NULL) {
+		struct nft_trans_instruction_context *ctx;
+		enum nft_instruction instr;
+
+		ctx = calloc(1, sizeof(struct nft_trans_instruction_context));
+		if (ctx == NULL)
+			goto error;
+
+		instr = str2nft_intruction(nft_rule_expr_get_str(expr,
+						NFT_RULE_EXPR_ATTR_NAME));
+		if (instr == NFT_INSTRUCTION_MAX)
+			goto error;
+
+		ctx->current_expr = expr;
+		ctx->instruction = instr;
+		ctx->registers = cur_regs;
+
+		if (cur_ctx == NULL)
+			rule_ctx->instr_contexts = ctx;
+		else
+			cur_ctx->next = ctx;
+
+		cur_ctx = ctx;
+
+		cur_regs = update_registers(instr, expr, cur_regs);
+		if (cur_regs == NULL)
+			goto error;
+
+		expr = nft_rule_expr_iter_next(iter);
+	}
+
+	if (cur_regs != NULL)
+		free(cur_regs);
+
+	nft_rule_expr_iter_destroy(iter);
+
+	return rule_ctx;
+
+error:
+	destroy_nft_trans_rule_context(rule_ctx);
+
+	if (cur_regs != NULL)
+		free(cur_regs);
+
+	if (iter != NULL)
+		nft_rule_expr_iter_destroy(iter);
+
+	return NULL;
+}
+
+static struct s_list *
+retrieve_nft_trans_instructions(struct nft_trans_instruction_tree *tree,
+				struct nft_trans_instruction_context *instructions)
+{
+	struct s_list *nft_trans_instructions = NULL;
+	struct nft_trans_instruction_context *ctx;
+	struct nft_trans_found_instruction *ipt_i;
+	struct nft_trans_instruction_node *node;
+
+	ctx = instructions;
+	node = tree->root;
+
+	while (ctx != NULL) {
+		if (node->nodes[ctx->instruction] != NULL) {
+			node = node->nodes[ctx->instruction];
+
+			if (node->functions != NULL) {
+				ipt_i = calloc(1,
+					sizeof(struct nft_trans_found_instruction));
+
+				ipt_i->functions = node->functions;
+				ipt_i->position = ctx;
+
+				/* It prepends since "longest path first"
+				 * is applied */
+				nft_trans_instructions = s_list_prepend(
+						nft_trans_instructions, ipt_i);
+			}
+		} else
+			break;
+
+		ctx = ctx->next;
+	};
+
+	return nft_trans_instructions;
+}
+
+static struct nft_trans_instruction_context *
+execute_relevant_instruction(struct s_list *instructions,
+			     struct nft_trans_rule_context *rule_ctx,
+			     struct nft_trans_instruction_context *position,
+			     nft_trans_parse_callback_f user_cb,
+			     void *user_data)
+{
+	for (; instructions != NULL; instructions = instructions->next) {
+		struct nft_trans_found_instruction *i_f = instructions->data;
+		const struct s_list *fl;
+
+		for (fl = i_f->functions; fl != NULL; fl = fl->next) {
+			nft_trans_parse_instruction_f function = fl->data;
+
+			if (function(rule_ctx, position, i_f->position,
+						user_cb, user_data) == 0)
+				return i_f->position;
+		}
+	}
+
+	return NULL;
+}
+
+int
+nft_trans_rule_translate_to_instructions(struct nft_trans_instruction_tree *tree,
+					 struct nft_rule *rule,
+					 nft_trans_parse_callback_f user_cb,
+					 void *user_data)
+{
+	struct nft_trans_instruction_context *position;
+	struct s_list *nft_trans_instructions;
+	struct nft_trans_rule_context *rule_ctx;
+
+	if (tree == NULL)
+		return -1;
+
+	rule_ctx = generate_nft_trans_rule_context(rule);
+	if (rule_ctx == NULL)
+		return -1;
+
+	position = rule_ctx->instr_contexts;
+	while (position != NULL) {
+		struct nft_trans_instruction_context *pos;
+
+		nft_trans_instructions = retrieve_nft_trans_instructions(tree,
+								position);
+		if (nft_trans_instructions == NULL)
+			goto error;
+
+		pos = execute_relevant_instruction(nft_trans_instructions,
+				rule_ctx, position, user_cb, user_data);
+		if (pos == NULL)
+			goto error;
+
+		s_list_free(nft_trans_instructions, 1, NULL);
+		position = pos->next;
+	}
+
+	destroy_nft_trans_rule_context(rule_ctx);
+
+	return 0;
+
+error:
+	s_list_free(nft_trans_instructions, 1, NULL);
+	destroy_nft_trans_rule_context(rule_ctx);
+
+	return -1;
+}
+
+struct nft_trans_instruction_context *
+nft_trans_instruction_context_get_next(struct nft_trans_instruction_context *i_ctx)
+{
+	if (i_ctx == NULL)
+		return NULL;
+
+	return i_ctx->next;
+}
+
+struct nft_rule_expr *
+nft_trans_instruction_context_get_expr(struct nft_trans_instruction_context *i_ctx)
+{
+	if (i_ctx == NULL)
+		return NULL;
+
+	return i_ctx->current_expr;
+}
+
+struct nft_rule_expr *
+nft_trans_instruction_context_get_register(struct nft_trans_instruction_context *i_ctx,
+					int register_index)
+{
+	if (i_ctx == NULL || i_ctx->registers == NULL ||
+					register_index >= NFT_REG_MAX)
+		return NULL;
+
+	return i_ctx->registers->reg[register_index];
+}
+
-- 
1.8.3.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] 18+ messages in thread

* [iptables-nftables - RFC v2 PATCH  05/17] nft: Integrate nft translator engine in current core
  2013-07-25 17:16 [iptables-nftables - RFC v2 PATCH 00/17] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
                   ` (3 preceding siblings ...)
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 04/17] nft: Add nft expressions translation engine as a library Tomasz Bursztyka
@ 2013-07-25 17:16 ` Tomasz Bursztyka
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 06/17] nft: Manage xtables target parsing through translation tree Tomasz Bursztyka
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Tomasz Bursztyka @ 2013-07-25 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

First step of using the nft translation engine: supporting basic rule
information to recreat the command structure.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 iptables/Makefile.am  |   2 +-
 iptables/nft-ipv4.c   |  23 ++++-
 iptables/nft-ipv6.c   |   9 +-
 iptables/nft-shared.c |  23 +++--
 iptables/nft-shared.h |  10 +-
 iptables/nft.c        | 249 +++++++++++++++++++++++++++++++++++---------------
 6 files changed, 225 insertions(+), 91 deletions(-)

diff --git a/iptables/Makefile.am b/iptables/Makefile.am
index dc8af34..3a7983c 100644
--- a/iptables/Makefile.am
+++ b/iptables/Makefile.am
@@ -32,7 +32,7 @@ xtables_multi_SOURCES += xtables-save.c xtables-restore.c \
 			 xtables-standalone.c xtables.c nft.c \
 			 nft-shared.c nft-ipv4.c nft-ipv6.c \
 			 xtables-config.c xtables-events.c
-xtables_multi_LDADD   += -lmnl -lnftables ${libmnl_LIBS} ${libnftables_LIBS}
+xtables_multi_LDADD   += -lmnl -lnftables ${libmnl_LIBS} ${libnftables_LIBS} ../libnfttrans/libnfttrans.la
 xtables_multi_CFLAGS  += -DENABLE_NFTABLES
 # yacc and lex generate dirty code
 xtables_multi-xtables-config-parser.o xtables_multi-xtables-config-syntax.o: AM_CFLAGS += -Wno-missing-prototypes -Wno-missing-declarations -Wno-implicit-function-declaration -Wno-nested-externs -Wno-undef -Wno-redundant-decls
diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c
index 51ee422..4b8f146 100644
--- a/iptables/nft-ipv4.c
+++ b/iptables/nft-ipv4.c
@@ -85,6 +85,18 @@ static bool nft_ipv4_is_same(const struct iptables_command_state *a,
 				  b->fw.ip.iniface_mask, b->fw.ip.outiface_mask);
 }
 
+static void get_frag_from_expr(struct nft_rule_expr *e, bool *inv)
+{
+	uint8_t op;
+
+	/* e is directly pointing to the cmp expr */
+	op = nft_rule_expr_get_u8(e, NFT_EXPR_CMP_OP);
+	if (op == NFT_CMP_EQ)
+		*inv = true;
+	else
+		*inv = false;
+}
+
 static void get_frag(struct nft_rule_expr_iter *iter, bool *inv)
 {
 	struct nft_rule_expr *e;
@@ -207,7 +219,8 @@ static void nft_ipv4_parse_meta(struct nft_rule_expr *e, uint8_t key,
 		   &cs->fw.ip.invflags);
 }
 
-static void nft_ipv4_parse_payload(struct nft_rule_expr_iter *iter,
+static void nft_ipv4_parse_payload(struct nft_rule_expr *e_1,
+				   struct nft_rule_expr *e_2,
 				   struct iptables_command_state *cs,
 				   uint32_t offset)
 {
@@ -217,28 +230,28 @@ static void nft_ipv4_parse_payload(struct nft_rule_expr_iter *iter,
 	bool inv;
 
 	case offsetof(struct iphdr, saddr):
-		get_cmp_data(iter, &addr, sizeof(addr), &inv);
+		get_expr_cmp_data(e_1, &addr, sizeof(addr), &inv);
 		cs->fw.ip.src.s_addr = addr.s_addr;
 		cs->fw.ip.smsk.s_addr = 0xffffffff;
 		if (inv)
 			cs->fw.ip.invflags |= IPT_INV_SRCIP;
 		break;
 	case offsetof(struct iphdr, daddr):
-		get_cmp_data(iter, &addr, sizeof(addr), &inv);
+		get_expr_cmp_data(e_1, &addr, sizeof(addr), &inv);
 		cs->fw.ip.dst.s_addr = addr.s_addr;
 		cs->fw.ip.dmsk.s_addr = 0xffffffff;
 		if (inv)
 			cs->fw.ip.invflags |= IPT_INV_DSTIP;
 		break;
 	case offsetof(struct iphdr, protocol):
-		get_cmp_data(iter, &proto, sizeof(proto), &inv);
+		get_expr_cmp_data(e_1, &proto, sizeof(proto), &inv);
 		cs->fw.ip.proto = proto;
 		if (inv)
 			cs->fw.ip.invflags |= IPT_INV_PROTO;
 		break;
 	case offsetof(struct iphdr, frag_off):
 		cs->fw.ip.flags |= IPT_F_FRAG;
-		get_frag(iter, &inv);
+		get_frag_from_expr(e_2, &inv);
 		if (inv)
 			cs->fw.ip.invflags |= IPT_INV_FRAG;
 		break;
diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c
index 61c660a..e5c8db9 100644
--- a/iptables/nft-ipv6.c
+++ b/iptables/nft-ipv6.c
@@ -119,7 +119,8 @@ static void nft_ipv6_parse_meta(struct nft_rule_expr *e, uint8_t key,
 		   cs->fw6.ipv6.outiface_mask, &cs->fw6.ipv6.invflags);
 }
 
-static void nft_ipv6_parse_payload(struct nft_rule_expr_iter *iter,
+static void nft_ipv6_parse_payload(struct nft_rule_expr *e_1,
+				   struct nft_rule_expr *e_2,
 				   struct iptables_command_state *cs,
 				   uint32_t offset)
 {
@@ -129,19 +130,19 @@ static void nft_ipv6_parse_payload(struct nft_rule_expr_iter *iter,
 	bool inv;
 
 	case offsetof(struct ip6_hdr, ip6_src):
-		get_cmp_data(iter, &addr, sizeof(addr), &inv);
+		get_expr_cmp_data(e_1, &addr, sizeof(addr), &inv);
 		memcpy(cs->fw6.ipv6.src.s6_addr, &addr, sizeof(addr));
 		if (inv)
 			cs->fw6.ipv6.invflags |= IPT_INV_SRCIP;
 		break;
 	case offsetof(struct ip6_hdr, ip6_dst):
-		get_cmp_data(iter, &addr, sizeof(addr), &inv);
+		get_expr_cmp_data(e_1, &addr, sizeof(addr), &inv);
 		memcpy(cs->fw6.ipv6.dst.s6_addr, &addr, sizeof(addr));
 		if (inv)
 			cs->fw6.ipv6.invflags |= IPT_INV_DSTIP;
 		break;
 	case offsetof(struct ip6_hdr, ip6_nxt):
-		get_cmp_data(iter, &proto, sizeof(proto), &inv);
+		get_expr_cmp_data(e_1, &proto, sizeof(proto), &inv);
 		cs->fw6.ipv6.flags |= IP6T_F_PROTO;
 		cs->fw6.ipv6.proto = proto;
 		if (inv)
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
index c0ee4c8..99a7681 100644
--- a/iptables/nft-shared.c
+++ b/iptables/nft-shared.c
@@ -292,21 +292,16 @@ void print_proto(uint16_t proto, int invert)
 	printf("-p %u ", proto);
 }
 
-void get_cmp_data(struct nft_rule_expr_iter *iter,
-		  void *data, size_t dlen, bool *inv)
+void get_expr_cmp_data(struct nft_rule_expr *e,
+		       void *data, size_t dlen, bool *inv)
 {
-	struct nft_rule_expr *e;
 	const char *name;
 	size_t len;
 	uint8_t op;
 
-	e = nft_rule_expr_iter_next(iter);
-	if (e == NULL)
-		return;
-
 	name = nft_rule_expr_get_str(e, NFT_RULE_EXPR_ATTR_NAME);
 	if (strcmp(name, "cmp") != 0) {
-		DEBUGP("skipping no cmp after meta\n");
+		DEBUGP("skipping - Not a cmp expression\n");
 		return;
 	}
 
@@ -318,6 +313,18 @@ void get_cmp_data(struct nft_rule_expr_iter *iter,
 		*inv = false;
 }
 
+void get_cmp_data(struct nft_rule_expr_iter *iter,
+		  void *data, size_t dlen, bool *inv)
+{
+	struct nft_rule_expr *e;
+
+	e = nft_rule_expr_iter_next(iter);
+	if (e == NULL)
+		return;
+
+	get_expr_cmp_data(e, data, dlen, inv);
+}
+
 void print_num(uint64_t number, unsigned int format)
 {
 	if (format & FMT_KILOMEGAGIGA) {
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
index c59ab21..2c199b4 100644
--- a/iptables/nft-shared.h
+++ b/iptables/nft-shared.h
@@ -44,7 +44,8 @@ struct nft_family_ops {
 			      struct nft_rule_expr_iter *iter);
 	void (*parse_meta)(struct nft_rule_expr *e, uint8_t key,
 			   struct iptables_command_state *cs);
-	void (*parse_payload)(struct nft_rule_expr_iter *iter,
+	void (*parse_payload)(struct nft_rule_expr *e_1,
+			      struct nft_rule_expr *e_2,
 			      struct iptables_command_state *cs,
 			      uint32_t offset);
 	void (*parse_immediate)(struct iptables_command_state *cs);
@@ -82,6 +83,8 @@ void parse_meta(struct nft_rule_expr *e, uint8_t key, char *iniface,
 		unsigned char *outiface_mask, uint8_t *invflags);
 
 void print_proto(uint16_t proto, int invert);
+void get_expr_cmp_data(struct nft_rule_expr *e,
+		       void *data, size_t dlen, bool *inv);
 void get_cmp_data(struct nft_rule_expr_iter *iter,
 		  void *data, size_t dlen, bool *inv);
 void print_num(uint64_t number, unsigned int format);
@@ -121,6 +124,11 @@ struct xtables_args {
 	unsigned long long pcnt_cnt, bcnt_cnt;
 };
 
+struct nft_to_cs_data {
+	int family;
+	struct iptables_command_state *cs;
+};
+
 #define CMD_NONE		0x0000U
 #define CMD_INSERT		0x0001U
 #define CMD_DELETE		0x0002U
diff --git a/iptables/nft.c b/iptables/nft.c
index 685a203..7a44e4d 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -46,12 +46,16 @@
 #include <netinet/in.h>	/* inet_ntoa */
 #include <arpa/inet.h>
 
+#include <nft-translator.h>
 #include "nft.h"
 #include "xshared.h" /* proto_to_name */
 #include "nft-shared.h"
 #include "xtables-config-parser.h"
 
+static void initiate_nft_translation_tree(void);
+
 static void *nft_fn;
+struct nft_trans_instruction_tree *xt_nft_tree;
 
 static int mnl_talk(struct nft_handle *h, struct nlmsghdr *nlh,
 		    int (*cb)(const struct nlmsghdr *nlh, void *data),
@@ -403,6 +407,8 @@ int nft_init(struct nft_handle *h)
 	}
 	h->portid = mnl_socket_get_portid(h->nl);
 
+	initiate_nft_translation_tree();
+
 	return 0;
 }
 
@@ -1684,106 +1690,142 @@ next:
 	return 0;
 }
 
-static void
-nft_parse_meta(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter,
-	       int family, struct iptables_command_state *cs)
-{
-	uint8_t key = nft_rule_expr_get_u8(e, NFT_EXPR_META_KEY);
-	struct nft_family_ops *ops = nft_family_ops_lookup(family);
-	const char *name;
-
-	e = nft_rule_expr_iter_next(iter);
-	if (e == NULL)
-		return;
-
-	name = nft_rule_expr_get_str(e, NFT_RULE_EXPR_ATTR_NAME);
-	if (strcmp(name, "cmp") != 0) {
-		DEBUGP("skipping no cmp after meta\n");
-		return;
-	}
-
-	ops->parse_meta(e, key, cs);
-}
-
-static void
-nft_parse_payload(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter,
-		  int family, struct iptables_command_state *cs)
+static int nft_parse_counters(struct nft_trans_rule_context *rule_ctx,
+			      struct nft_trans_instruction_context *first,
+			      struct nft_trans_instruction_context *useless,
+			      nft_trans_parse_callback_f user_cb,
+			      void *user_data)
 {
-	struct nft_family_ops *ops = nft_family_ops_lookup(family);
-	uint32_t offset;
+	struct nft_to_cs_data *i2cs = user_data;
+	struct xt_counters *counters;
+	struct nft_rule_expr *e;
 
-	offset = nft_rule_expr_get_u32(e, NFT_EXPR_PAYLOAD_OFFSET);
+	e = nft_trans_instruction_context_get_expr(first);
 
-	ops->parse_payload(iter, cs, offset);
-}
+	if (!nft_rule_expr_is_set(e, NFT_EXPR_CTR_PACKETS) ||
+				!nft_rule_expr_is_set(e, NFT_EXPR_CTR_BYTES))
+		return -1;
 
-static void
-nft_parse_counter(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter,
-		  struct xt_counters *counters)
-{
+	counters = &i2cs->cs->counters;
 	counters->pcnt = nft_rule_expr_get_u64(e, NFT_EXPR_CTR_PACKETS);
 	counters->bcnt = nft_rule_expr_get_u64(e, NFT_EXPR_CTR_BYTES);
+
+	return 0;
 }
 
-static void
-nft_parse_immediate(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter,
-		    int family, struct iptables_command_state *cs)
+static int nft_parse_verdict(struct nft_trans_rule_context *rule_ctx,
+			     struct nft_trans_instruction_context *first,
+			     struct nft_trans_instruction_context *useless,
+			     nft_trans_parse_callback_f user_cb,
+			     void *user_data)
 {
-	int verdict = nft_rule_expr_get_u32(e, NFT_EXPR_IMM_VERDICT);
-	const char *chain = nft_rule_expr_get_str(e, NFT_EXPR_IMM_CHAIN);
+	struct nft_to_cs_data *i2cs = user_data;
 	struct nft_family_ops *ops;
+	struct nft_rule_expr *e;
+	const char *chain;
+	int verdict;
 
+	e = nft_trans_instruction_context_get_expr(first);
+
+	if (!nft_rule_expr_is_set(e, NFT_EXPR_IMM_VERDICT))
+		return -1;
+
+	verdict = nft_rule_expr_get_u32(e, NFT_EXPR_IMM_VERDICT);
 	/* Standard target? */
 	switch(verdict) {
 	case NF_ACCEPT:
-		cs->jumpto = "ACCEPT";
-		return;
+		i2cs->cs->jumpto = "ACCEPT";
+		break;
 	case NF_DROP:
-		cs->jumpto = "DROP";
-		return;
+		i2cs->cs->jumpto = "DROP";
+		break;
 	case NFT_RETURN:
-		cs->jumpto = "RETURN";
-		return;
+		i2cs->cs->jumpto = "RETURN";
+		break;
 	case NFT_GOTO:
-		ops = nft_family_ops_lookup(family);
-		ops->parse_immediate(cs);
+		ops = nft_family_ops_lookup(i2cs->family);
+		ops->parse_immediate(i2cs->cs);
 	case NFT_JUMP:
-		cs->jumpto = chain;
-		return;
+		if (!nft_rule_expr_is_set(e, NFT_EXPR_IMM_CHAIN))
+			return -1;
+
+		chain = nft_rule_expr_get_str(e, NFT_EXPR_IMM_CHAIN);
+		i2cs->cs->jumpto = chain;
+		break;
 	}
+
+	return 0;
+}
+
+static int nft_parse_io_ifs(struct nft_trans_rule_context *rule_ctx,
+			    struct nft_trans_instruction_context *first,
+			    struct nft_trans_instruction_context *second,
+			    nft_trans_parse_callback_f user_cb,
+			    void *user_data)
+{
+	struct nft_to_cs_data *i2cs = user_data;
+	struct nft_family_ops *ops;
+	struct nft_rule_expr *e;
+	uint8_t key;
+
+	e = nft_trans_instruction_context_get_expr(first);
+	if (!nft_rule_expr_is_set(e, NFT_EXPR_META_KEY))
+		return -1;
+
+	key = nft_rule_expr_get_u8(e, NFT_EXPR_META_KEY);
+	ops = nft_family_ops_lookup(i2cs->family);
+
+	e = nft_trans_instruction_context_get_expr(second);
+	ops->parse_meta(e, key, i2cs->cs);
+
+	return 0;
+}
+
+static int nft_parse_ip_addresses(struct nft_trans_rule_context *rule_ctx,
+				  struct nft_trans_instruction_context *first,
+				  struct nft_trans_instruction_context *last,
+				  nft_trans_parse_callback_f user_cb,
+				  void *user_data)
+{
+	struct nft_to_cs_data *i2cs = user_data;
+	struct nft_rule_expr *e1, *e2;
+	struct nft_family_ops *ops;
+	uint32_t offset;
+
+	e1 = nft_trans_instruction_context_get_expr(first);
+	if (!nft_rule_expr_is_set(e1, NFT_EXPR_PAYLOAD_OFFSET))
+		return -1;
+
+	offset = nft_rule_expr_get_u32(e1, NFT_EXPR_PAYLOAD_OFFSET);
+	ops = nft_family_ops_lookup(i2cs->family);
+
+	first = nft_trans_instruction_context_get_next(first);
+	e1 = nft_trans_instruction_context_get_expr(first);
+	e2 = nft_trans_instruction_context_get_expr(last);
+
+	ops->parse_payload(e1, e2, i2cs->cs, offset);
+
+	return 0;
 }
 
 static void
 nft_rule_to_iptables_command_state(struct nft_rule *r,
 				   struct iptables_command_state *cs)
 {
-	struct nft_rule_expr_iter *iter;
-	struct nft_rule_expr *expr;
-	int family = nft_rule_attr_get_u8(r, NFT_RULE_ATTR_FAMILY);
-
-	iter = nft_rule_expr_iter_create(r);
-	if (iter == NULL)
-		return;
-
-	expr = nft_rule_expr_iter_next(iter);
-	while (expr != NULL) {
-		const char *name =
-			nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME);
+	struct nft_to_cs_data i2cs = {};
 
-		if (strcmp(name, "counter") == 0) {
-			nft_parse_counter(expr, iter, &cs->counters);
-		} else if (strcmp(name, "payload") == 0) {
-			nft_parse_payload(expr, iter, family, cs);
-		} else if (strcmp(name, "meta") == 0) {
-			nft_parse_meta(expr, iter, family, cs);
-		} else if (strcmp(name, "immediate") == 0) {
-			nft_parse_immediate(expr, iter, family, cs);
-		}
+	i2cs.family = nft_rule_attr_get_u8(r, NFT_RULE_ATTR_FAMILY);
+	i2cs.cs = cs;
 
-		expr = nft_rule_expr_iter_next(iter);
-	}
+	nft_trans_rule_translate_to_instructions(xt_nft_tree, r, NULL, &i2cs);
 
-	nft_rule_expr_iter_destroy(iter);
+	if (i2cs.cs->target != NULL)
+		i2cs.cs->jumpto = i2cs.cs->target->name;
+	else if (i2cs.cs->jumpto != NULL)
+		i2cs.cs->target = xtables_find_target(i2cs.cs->jumpto,
+								XTF_TRY_LOAD);
+	else
+		i2cs.cs->jumpto = "";
 }
 
 static int matches_howmany(struct xtables_rule_match *matches)
@@ -2839,6 +2881,69 @@ static void xtables_config_perror(uint32_t flags, const char *fmt, ...)
 	va_end(args);
 }
 
+static enum nft_instruction nft_ipt_counters_instructions[] = {
+	NFT_INSTRUCTION_COUNTER,
+	NFT_INSTRUCTION_MAX,
+};
+
+static struct nft_trans_instruction nft_ipt_counters = {
+	.instructions = nft_ipt_counters_instructions,
+	.function = nft_parse_counters,
+};
+
+static enum nft_instruction nft_ipt_verdict_instructions[] = {
+	NFT_INSTRUCTION_IMMEDIATE,
+	NFT_INSTRUCTION_MAX,
+};
+
+static struct nft_trans_instruction nft_ipt_verdict = {
+	.instructions = nft_ipt_verdict_instructions,
+	.function = nft_parse_verdict,
+};
+
+static enum nft_instruction nft_ipt_io_ifs_instructions[] = {
+	NFT_INSTRUCTION_META, NFT_INSTRUCTION_CMP,
+	NFT_INSTRUCTION_MAX,
+};
+
+static struct nft_trans_instruction nft_ipt_io_ifs = {
+	.instructions = nft_ipt_io_ifs_instructions,
+	.function = nft_parse_io_ifs,
+};
+
+static enum nft_instruction nft_ipt_ip_addr_instructions_1[] = {
+	NFT_INSTRUCTION_PAYLOAD, NFT_INSTRUCTION_CMP,
+	NFT_INSTRUCTION_MAX,
+};
+
+static struct nft_trans_instruction nft_ipt_ip_addr_1 = {
+	.instructions = nft_ipt_ip_addr_instructions_1,
+	.function = nft_parse_ip_addresses,
+};
+
+static enum nft_instruction nft_ipt_ip_addr_instructions_2[] = {
+	NFT_INSTRUCTION_PAYLOAD, NFT_INSTRUCTION_BITWISE, NFT_INSTRUCTION_CMP,
+	NFT_INSTRUCTION_MAX,
+};
+
+static struct nft_trans_instruction nft_ipt_ip_addr_2 = {
+	.instructions = nft_ipt_ip_addr_instructions_2,
+	.function = nft_parse_ip_addresses,
+};
+
+static void initiate_nft_translation_tree(void)
+{
+	xt_nft_tree = nft_trans_instruction_tree_new();
+	if (xt_nft_tree == NULL)
+		return;
+
+	nft_trans_add_instruction(xt_nft_tree, &nft_ipt_counters);
+	nft_trans_add_instruction(xt_nft_tree, &nft_ipt_verdict);
+	nft_trans_add_instruction(xt_nft_tree, &nft_ipt_io_ifs);
+	nft_trans_add_instruction(xt_nft_tree, &nft_ipt_ip_addr_1);
+	nft_trans_add_instruction(xt_nft_tree, &nft_ipt_ip_addr_2);
+}
+
 int nft_xtables_config_load(struct nft_handle *h, const char *filename,
 			    uint32_t flags)
 {
-- 
1.8.3.2


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

* [iptables-nftables - RFC v2 PATCH  06/17] nft: Manage xtables target parsing through translation tree
  2013-07-25 17:16 [iptables-nftables - RFC v2 PATCH 00/17] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
                   ` (4 preceding siblings ...)
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 05/17] nft: Integrate nft translator engine in current core Tomasz Bursztyka
@ 2013-07-25 17:16 ` Tomasz Bursztyka
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 07/17] nft: Manage xtables matches through nft " Tomasz Bursztyka
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Tomasz Bursztyka @ 2013-07-25 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

This add the support of compatible layer for xtables target extension through
the nft translator. Thus feeding give command structure with the right target.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 iptables/Makefile.am  |  1 +
 iptables/nft-xt-ext.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++
 iptables/nft-xt-ext.h | 12 ++++++++
 iptables/nft.c        |  3 ++
 4 files changed, 101 insertions(+)
 create mode 100644 iptables/nft-xt-ext.c
 create mode 100644 iptables/nft-xt-ext.h

diff --git a/iptables/Makefile.am b/iptables/Makefile.am
index 3a7983c..7ba2990 100644
--- a/iptables/Makefile.am
+++ b/iptables/Makefile.am
@@ -31,6 +31,7 @@ xtables_multi_SOURCES += xtables-config-parser.y xtables-config-syntax.l
 xtables_multi_SOURCES += xtables-save.c xtables-restore.c \
 			 xtables-standalone.c xtables.c nft.c \
 			 nft-shared.c nft-ipv4.c nft-ipv6.c \
+			 nft-xt-ext.c \
 			 xtables-config.c xtables-events.c
 xtables_multi_LDADD   += -lmnl -lnftables ${libmnl_LIBS} ${libnftables_LIBS} ../libnfttrans/libnfttrans.la
 xtables_multi_CFLAGS  += -DENABLE_NFTABLES
diff --git a/iptables/nft-xt-ext.c b/iptables/nft-xt-ext.c
new file mode 100644
index 0000000..70ffe35
--- /dev/null
+++ b/iptables/nft-xt-ext.c
@@ -0,0 +1,85 @@
+/*
+ * (C) 2013 by Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <xtables.h>
+
+#include <nft-xt-ext.h>
+#include <nft-shared.h>
+
+static int nft_parse_xt_target(struct nft_trans_rule_context *rule_ctx,
+			       struct nft_trans_instruction_context *first,
+			       struct nft_trans_instruction_context *useless,
+			       nft_trans_parse_callback_f user_cb,
+			       void *user_data)
+{
+	struct nft_to_cs_data *i2cs = user_data;
+	struct xtables_target *target;
+	struct xt_entry_target *t;
+	struct nft_rule_expr *e;
+	const char *target_name;
+	const void *info;
+	size_t length;
+	uint32_t rev;
+
+	e = nft_trans_instruction_context_get_expr(first);
+
+	if (!nft_rule_expr_is_set(e, NFT_EXPR_TG_NAME) ||
+				!nft_rule_expr_is_set(e, NFT_EXPR_TG_REV) ||
+				!nft_rule_expr_is_set(e, NFT_EXPR_TG_INFO))
+		return -1;
+
+	target_name = nft_rule_expr_get_str(e, NFT_EXPR_TG_NAME);
+	if (target_name == NULL)
+		return -1;
+
+	target = xtables_find_target(target_name, XTF_TRY_LOAD);
+	if (target == NULL)
+		return -1;
+
+	info = nft_rule_expr_get(e, NFT_EXPR_TG_INFO, &length);
+
+	t = calloc(1, sizeof(struct xt_entry_target) + length);
+	if (t == NULL)
+		return -1;
+
+	memcpy(&t->data, info, length);
+	t->u.target_size = length + XT_ALIGN(sizeof(struct xt_entry_target));
+
+	rev = nft_rule_expr_get_u32(e, NFT_EXPR_TG_REV);
+	t->u.user.revision = rev;
+	strcpy(t->u.user.name, target->name);
+
+	target->t = t;
+	i2cs->cs->target = target;
+
+	return 0;
+}
+
+static enum nft_instruction nft_ipt_xt_target_instructions[] = {
+	NFT_INSTRUCTION_TARGET,
+	NFT_INSTRUCTION_MAX,
+};
+
+static struct nft_trans_instruction nft_ipt_xt_target = {
+	.instructions = nft_ipt_xt_target_instructions,
+	.function = nft_parse_xt_target,
+};
+
+int nft_xt_ext_into_translation_tree(struct nft_trans_instruction_tree *tree)
+{
+	if (tree == NULL)
+		return -1;
+
+	nft_trans_add_instruction(tree, &nft_ipt_xt_target);
+
+	return 0;
+}
diff --git a/iptables/nft-xt-ext.h b/iptables/nft-xt-ext.h
new file mode 100644
index 0000000..a367277
--- /dev/null
+++ b/iptables/nft-xt-ext.h
@@ -0,0 +1,12 @@
+/*
+ * (C) 2013 by Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <nft-translator.h>
+
+int nft_xt_ext_into_translation_tree(struct nft_trans_instruction_tree *tree);
diff --git a/iptables/nft.c b/iptables/nft.c
index 7a44e4d..7b16bd3 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -51,6 +51,7 @@
 #include "xshared.h" /* proto_to_name */
 #include "nft-shared.h"
 #include "xtables-config-parser.h"
+#include "nft-xt-ext.h"
 
 static void initiate_nft_translation_tree(void);
 
@@ -2942,6 +2943,8 @@ static void initiate_nft_translation_tree(void)
 	nft_trans_add_instruction(xt_nft_tree, &nft_ipt_io_ifs);
 	nft_trans_add_instruction(xt_nft_tree, &nft_ipt_ip_addr_1);
 	nft_trans_add_instruction(xt_nft_tree, &nft_ipt_ip_addr_2);
+
+	nft_xt_ext_into_translation_tree(xt_nft_tree);
 }
 
 int nft_xtables_config_load(struct nft_handle *h, const char *filename,
-- 
1.8.3.2


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

* [iptables-nftables - RFC v2 PATCH  07/17] nft: Manage xtables matches through nft translation tree
  2013-07-25 17:16 [iptables-nftables - RFC v2 PATCH 00/17] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
                   ` (5 preceding siblings ...)
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 06/17] nft: Manage xtables target parsing through translation tree Tomasz Bursztyka
@ 2013-07-25 17:16 ` Tomasz Bursztyka
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 08/17] nft: Add support for xtables extensions callback to change cs Tomasz Bursztyka
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Tomasz Bursztyka @ 2013-07-25 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

This add the support of compatible layer for xtables matches extension through
the nft translator. Thus feeding give command structure with the right matches.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 iptables/nft-xt-ext.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/iptables/nft-xt-ext.c b/iptables/nft-xt-ext.c
index 70ffe35..f013493 100644
--- a/iptables/nft-xt-ext.c
+++ b/iptables/nft-xt-ext.c
@@ -64,6 +64,55 @@ static int nft_parse_xt_target(struct nft_trans_rule_context *rule_ctx,
 	return 0;
 }
 
+static int nft_parse_xt_match(struct nft_trans_rule_context *rule_ctx,
+			      struct nft_trans_instruction_context *first,
+			      struct nft_trans_instruction_context *useless,
+			      nft_trans_parse_callback_f user_cb,
+			      void *user_data)
+{
+	struct nft_to_cs_data *i2cs = user_data;
+	struct xtables_match *match;
+	struct xt_entry_match *m;
+	struct nft_rule_expr *e;
+	const char *match_name;
+	const void *info;
+	size_t length;
+	uint32_t rev;
+
+	e = nft_trans_instruction_context_get_expr(first);
+
+	if (!nft_rule_expr_is_set(e, NFT_EXPR_MT_NAME) ||
+				!nft_rule_expr_is_set(e, NFT_EXPR_MT_REV) ||
+				!nft_rule_expr_is_set(e, NFT_EXPR_MT_INFO))
+		return -1;
+
+	match_name = nft_rule_expr_get_str(e, NFT_EXPR_MT_NAME);
+	if (match_name == NULL)
+		return -1;
+
+	match = xtables_find_match(match_name,
+					XTF_TRY_LOAD, &i2cs->cs->matches);
+	if (match == NULL)
+		return -1;
+
+	info = nft_rule_expr_get(e, NFT_EXPR_TG_INFO, &length);
+
+	m = calloc(1, sizeof(struct xt_entry_match) + length);
+	if (m == NULL)
+		return -1;
+
+	memcpy(&m->data, info, length);
+	m->u.match_size = length + XT_ALIGN(sizeof(struct xt_entry_match));
+
+	rev = nft_rule_expr_get_u32(e, NFT_EXPR_TG_REV);
+	m->u.user.revision = rev;
+	strcpy(m->u.user.name, match->name);
+
+	match->m = m;
+
+	return 0;
+}
+
 static enum nft_instruction nft_ipt_xt_target_instructions[] = {
 	NFT_INSTRUCTION_TARGET,
 	NFT_INSTRUCTION_MAX,
@@ -74,12 +123,23 @@ static struct nft_trans_instruction nft_ipt_xt_target = {
 	.function = nft_parse_xt_target,
 };
 
+static enum nft_instruction nft_ipt_xt_match_instructions[] = {
+	NFT_INSTRUCTION_MATCH,
+	NFT_INSTRUCTION_MAX,
+};
+
+static struct nft_trans_instruction nft_ipt_xt_match = {
+	.instructions = nft_ipt_xt_match_instructions,
+	.function = nft_parse_xt_match,
+};
+
 int nft_xt_ext_into_translation_tree(struct nft_trans_instruction_tree *tree)
 {
 	if (tree == NULL)
 		return -1;
 
 	nft_trans_add_instruction(tree, &nft_ipt_xt_target);
+	nft_trans_add_instruction(tree, &nft_ipt_xt_match);
 
 	return 0;
 }
-- 
1.8.3.2


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

* [iptables-nftables - RFC v2 PATCH  08/17] nft: Add support for xtables extensions callback to change cs
  2013-07-25 17:16 [iptables-nftables - RFC v2 PATCH 00/17] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
                   ` (6 preceding siblings ...)
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 07/17] nft: Manage xtables matches through nft " Tomasz Bursztyka
@ 2013-07-25 17:16 ` Tomasz Bursztyka
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 09/17] xtables: Add support for registering nft translation function for target Tomasz Bursztyka
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Tomasz Bursztyka @ 2013-07-25 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

This add the support of xtables extension expressed in pure nft through
the nft translator. Thus feeding give command structure with the right
target or match. This has been implemented as a callback, in the core,
to let the extentions being able to feed the command structure. Which
command structure they cannot handle (its declaration is private to the core).

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 iptables/nft-xt-ext.c | 20 ++++++++++++++++++++
 iptables/nft-xt-ext.h |  2 ++
 iptables/nft.c        |  3 ++-
 3 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/iptables/nft-xt-ext.c b/iptables/nft-xt-ext.c
index f013493..660e417 100644
--- a/iptables/nft-xt-ext.c
+++ b/iptables/nft-xt-ext.c
@@ -143,3 +143,23 @@ int nft_xt_ext_into_translation_tree(struct nft_trans_instruction_tree *tree)
 
 	return 0;
 }
+
+int nft_xt_ext_parse_callback(const char *ident, void *data, void *user_data)
+{
+	struct nft_to_cs_data *i2cs = user_data;
+	struct xtables_target *target;
+	struct xtables_match *match;
+
+	target = xtables_find_target(ident, XTF_TRY_LOAD);
+	match = xtables_find_match(ident, XTF_TRY_LOAD, &i2cs->cs->matches);
+
+	if (target != NULL) {
+		target->t = data;
+		i2cs->cs->target = target;
+	} else if (match != NULL)
+		match->m = data;
+	else
+		return -1;
+
+	return 0;
+}
diff --git a/iptables/nft-xt-ext.h b/iptables/nft-xt-ext.h
index a367277..f3e6491 100644
--- a/iptables/nft-xt-ext.h
+++ b/iptables/nft-xt-ext.h
@@ -10,3 +10,5 @@
 #include <nft-translator.h>
 
 int nft_xt_ext_into_translation_tree(struct nft_trans_instruction_tree *tree);
+
+int nft_xt_ext_parse_callback(const char *ident, void *data, void *user_data);
diff --git a/iptables/nft.c b/iptables/nft.c
index 7b16bd3..7b619b5 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -1818,7 +1818,8 @@ nft_rule_to_iptables_command_state(struct nft_rule *r,
 	i2cs.family = nft_rule_attr_get_u8(r, NFT_RULE_ATTR_FAMILY);
 	i2cs.cs = cs;
 
-	nft_trans_rule_translate_to_instructions(xt_nft_tree, r, NULL, &i2cs);
+	nft_trans_rule_translate_to_instructions(xt_nft_tree, r,
+					nft_xt_ext_parse_callback, &i2cs);
 
 	if (i2cs.cs->target != NULL)
 		i2cs.cs->jumpto = i2cs.cs->target->name;
-- 
1.8.3.2


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

* [iptables-nftables - RFC v2 PATCH  09/17] xtables: Add support for registering nft translation function for target
  2013-07-25 17:16 [iptables-nftables - RFC v2 PATCH 00/17] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
                   ` (7 preceding siblings ...)
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 08/17] nft: Add support for xtables extensions callback to change cs Tomasz Bursztyka
@ 2013-07-25 17:16 ` Tomasz Bursztyka
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 10/17] xtables: Add support for registering nft translation function for match Tomasz Bursztyka
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Tomasz Bursztyka @ 2013-07-25 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

Add the method which will be called by the core to register the xtables
target extensions into the nft translator. Through that method, the extension
will provide the combination of pattern/parser to the translation tree.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 extensions/GNUmakefile.in | 2 +-
 include/xtables.h         | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/extensions/GNUmakefile.in b/extensions/GNUmakefile.in
index da2f38b..5a19008 100644
--- a/extensions/GNUmakefile.in
+++ b/extensions/GNUmakefile.in
@@ -16,7 +16,7 @@ CCLD               = ${CC}
 CFLAGS             = @CFLAGS@
 CPPFLAGS           = @CPPFLAGS@
 LDFLAGS            = @LDFLAGS@
-@ENABLE_NFTABLES_TRUE@ LDFLAGS += @EXTENSION_NFT_LDFLAGS@
+@ENABLE_NFTABLES_TRUE@ LDFLAGS += @EXTENSION_NFT_LDFLAGS@ -L../libnfttrans/.libs -lnfttrans
 regular_CFLAGS     = @regular_CFLAGS@
 regular_CPPFLAGS   = @regular_CPPFLAGS@
 kinclude_CPPFLAGS  = @kinclude_CPPFLAGS@
diff --git a/include/xtables.h b/include/xtables.h
index 5bd8a59..fe1f31c 100644
--- a/include/xtables.h
+++ b/include/xtables.h
@@ -19,6 +19,7 @@
 #include <linux/netfilter/x_tables.h>
 
 #include <libnftables/rule.h>
+#include <nft-translator.h>
 
 #ifndef IPPROTO_SCTP
 #define IPPROTO_SCTP 132
@@ -353,6 +354,7 @@ struct xtables_target
 
 	/* NFT related */
 	int (*to_nft)(struct nft_rule *, struct xt_entry_target *);
+	int (*register_nft_instructions)(struct nft_trans_instruction_tree *);
 
 	size_t udata_size;
 
-- 
1.8.3.2


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

* [iptables-nftables - RFC v2 PATCH  10/17] xtables: Add support for registering nft translation function for match
  2013-07-25 17:16 [iptables-nftables - RFC v2 PATCH 00/17] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
                   ` (8 preceding siblings ...)
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 09/17] xtables: Add support for registering nft translation function for target Tomasz Bursztyka
@ 2013-07-25 17:16 ` Tomasz Bursztyka
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 11/17] nft: Register all relevant xtables extensions into translation tree Tomasz Bursztyka
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Tomasz Bursztyka @ 2013-07-25 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

Add the method which will be called by the core to register the xtables 
matches extensions into the nft translator. Through that method, the extension
will provide the combination of pattern/parser to the translation tree.


Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 include/xtables.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/xtables.h b/include/xtables.h
index fe1f31c..03139a0 100644
--- a/include/xtables.h
+++ b/include/xtables.h
@@ -274,6 +274,7 @@ struct xtables_match
 
 	/* NFT related */
 	int (*to_nft)(struct nft_rule *r, struct xt_entry_match *);
+	int (*register_nft_instructions)(struct nft_trans_instruction_tree *);
 
 	/* Size of per-extension instance extra "global" scratch space */
 	size_t udata_size;
-- 
1.8.3.2


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

* [iptables-nftables - RFC v2 PATCH  11/17] nft: Register all relevant xtables extensions into translation tree
  2013-07-25 17:16 [iptables-nftables - RFC v2 PATCH 00/17] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
                   ` (9 preceding siblings ...)
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 10/17] xtables: Add support for registering nft translation function for match Tomasz Bursztyka
@ 2013-07-25 17:16 ` Tomasz Bursztyka
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 12/17] nft: Refactor firewall printing so it reuses already parsed cs struct Tomasz Bursztyka
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Tomasz Bursztyka @ 2013-07-25 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

On the contrary of legacy code or current compatible xtables layer in nftables,
pure nft expression list, representing an extension, won't provide any extension
name.

What use to be one target expressions with a name and a data like for instance:
target(foo,<memory blob>)
will become:
imm bitwise cmp payload imm cmp

Thus, it's necessary to know the expression patterns, before hand to be able to
match the right extension.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 include/xtables.h     |  2 ++
 iptables/nft-xt-ext.c | 13 +++++++++++++
 2 files changed, 15 insertions(+)

diff --git a/include/xtables.h b/include/xtables.h
index 03139a0..0a07f22 100644
--- a/include/xtables.h
+++ b/include/xtables.h
@@ -422,6 +422,8 @@ extern "C" {
 #endif
 
 extern const char *xtables_modprobe_program;
+extern struct xtables_match *xtables_pending_matches;
+extern struct xtables_target *xtables_pending_targets;
 extern struct xtables_match *xtables_matches;
 extern struct xtables_target *xtables_targets;
 
diff --git a/iptables/nft-xt-ext.c b/iptables/nft-xt-ext.c
index 660e417..b2b29a7 100644
--- a/iptables/nft-xt-ext.c
+++ b/iptables/nft-xt-ext.c
@@ -135,12 +135,25 @@ static struct nft_trans_instruction nft_ipt_xt_match = {
 
 int nft_xt_ext_into_translation_tree(struct nft_trans_instruction_tree *tree)
 {
+	struct xtables_target *t;
+	struct xtables_match *m;
+
 	if (tree == NULL)
 		return -1;
 
 	nft_trans_add_instruction(tree, &nft_ipt_xt_target);
 	nft_trans_add_instruction(tree, &nft_ipt_xt_match);
 
+	for (t = xtables_pending_targets; t; t = t->next) {
+		if (t->register_nft_instructions != NULL)
+			t->register_nft_instructions(tree);
+	}
+
+	for (m = xtables_pending_matches; m; m = m->next) {
+		if (m->register_nft_instructions != NULL)
+			m->register_nft_instructions(tree);
+	}
+
 	return 0;
 }
 
-- 
1.8.3.2


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

* [iptables-nftables - RFC v2 PATCH  12/17] nft: Refactor firewall printing so it reuses already parsed cs struct
  2013-07-25 17:16 [iptables-nftables - RFC v2 PATCH 00/17] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
                   ` (10 preceding siblings ...)
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 11/17] nft: Register all relevant xtables extensions into translation tree Tomasz Bursztyka
@ 2013-07-25 17:16 ` Tomasz Bursztyka
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 13/17] nft: Refactor rule deletion so it compares both cs structure Tomasz Bursztyka
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Tomasz Bursztyka @ 2013-07-25 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

Now that we parse properly, in one place and at once, the rule back into a
command structure, it's now easier to print the rule from that command
structure.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 iptables/nft.c | 122 ++++++---------------------------------------------------
 1 file changed, 11 insertions(+), 111 deletions(-)

diff --git a/iptables/nft.c b/iptables/nft.c
index 7b619b5..2a0fa77 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -2357,95 +2357,18 @@ print_header(unsigned int format, const char *chain, const char *pol,
 }
 
 static void
-print_match(struct nft_rule_expr *expr, int numeric)
-{
-	size_t len;
-	const char *match_name = nft_rule_expr_get_str(expr, NFT_EXPR_MT_NAME);
-	const void *match_info = nft_rule_expr_get(expr, NFT_EXPR_MT_INFO, &len);
-	const struct xtables_match *match =
-		xtables_find_match(match_name, XTF_TRY_LOAD, NULL);
-	struct xt_entry_match *m =
-		calloc(1, sizeof(struct xt_entry_match) + len);
-
-	/* emulate struct xt_entry_match since ->print needs it */
-	memcpy((void *)&m->data, match_info, len);
-
-	if (match) {
-		if (match->print)
-			/* FIXME missing first parameter */
-			match->print(NULL, m, numeric);
-		else
-			printf("%s ", match_name);
-	} else {
-		if (match_name[0])
-			printf("UNKNOWN match `%s' ", match_name);
-	}
-
-	free(m);
-}
-
-static void
 print_firewall(const struct iptables_command_state *cs, struct nft_rule *r,
 	       unsigned int num, unsigned int format)
 {
-	const struct xtables_target *target = NULL;
-	const char *targname = NULL;
-	const void *targinfo = NULL;
-	int family;
+	struct xtables_rule_match *matchp;
 	struct nft_family_ops *ops;
 	uint8_t flags = 0;
-	struct nft_rule_expr_iter *iter;
-	struct nft_rule_expr *expr;
-	struct xt_entry_target *t;
-	size_t target_len = 0;
-
-	iter = nft_rule_expr_iter_create(r);
-	if (iter == NULL)
-		return;
-
-	expr = nft_rule_expr_iter_next(iter);
-	while (expr != NULL) {
-		const char *name =
-			nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME);
-
-		if (strcmp(name, "target") == 0) {
-			targname = nft_rule_expr_get_str(expr,
-							 NFT_EXPR_TG_NAME);
-			targinfo = nft_rule_expr_get(expr, NFT_EXPR_TG_INFO,
-						     &target_len);
-			break;
-		} else if (strcmp(name, "immediate") == 0) {
-			uint32_t verdict =
-			nft_rule_expr_get_u32(expr, NFT_EXPR_IMM_VERDICT);
-
-			switch(verdict) {
-			case NF_ACCEPT:
-				targname = "ACCEPT";
-				break;
-			case NF_DROP:
-				targname = "DROP";
-				break;
-			case NFT_RETURN:
-				targname = "RETURN";
-				break;
-			case NFT_GOTO:
-				targname = nft_rule_expr_get_str(expr,
-							NFT_EXPR_IMM_CHAIN);
-				break;
-			case NFT_JUMP:
-				targname = nft_rule_expr_get_str(expr,
-							NFT_EXPR_IMM_CHAIN);
-			break;
-			}
-		}
-		expr = nft_rule_expr_iter_next(iter);
-	}
-	nft_rule_expr_iter_destroy(iter);
+	int family;
 
 	family = nft_rule_attr_get_u8(r, NFT_RULE_ATTR_FAMILY);
 	ops = nft_family_ops_lookup(family);
 
-	flags = ops->print_firewall(cs, targname, num, format);
+	flags = ops->print_firewall(cs, cs->jumpto, num, format);
 
 	if (format & FMT_NOTABLE)
 		fputs("  ", stdout);
@@ -2455,40 +2378,17 @@ print_firewall(const struct iptables_command_state *cs, struct nft_rule *r,
 		printf("[goto] ");
 #endif
 
-	iter = nft_rule_expr_iter_create(r);
-	if (iter == NULL)
-		return;
-
-	expr = nft_rule_expr_iter_next(iter);
-	while (expr != NULL) {
-		const char *name =
-			nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME);
-
-		if (strcmp(name, "match") == 0)
-			print_match(expr, format & FMT_NUMERIC);
-
-		expr = nft_rule_expr_iter_next(iter);
+	for (matchp = cs->matches; matchp; matchp = matchp->next) {
+		if (matchp->match->print != NULL)
+			matchp->match->print(NULL, matchp->match->m,
+							format & FMT_NUMERIC);
 	}
-	nft_rule_expr_iter_destroy(iter);
 
-	t = calloc(1, sizeof(struct xt_entry_target) + target_len);
-	if (t == NULL)
-		return;
-
-	/* emulate struct xt_entry_match since ->print needs it */
-	memcpy((void *)&t->data, targinfo, target_len);
-
-	if (targname) {
-		target = xtables_find_target(targname, XTF_TRY_LOAD);
-		if (target) {
-			if (target->print)
-				/* FIXME missing first parameter */
-				target->print(NULL, t, format & FMT_NUMERIC);
-		} else
-			printf("[%ld bytes of unknown target data] ",
-				target_len);
+	if (cs->target != NULL) {
+		if (cs->target->print != NULL)
+			cs->target->print(NULL, cs->target->t,
+							format & FMT_NUMERIC);
 	}
-	free(t);
 
 	if (!(format & FMT_NONEWLINE))
 		fputc('\n', stdout);
-- 
1.8.3.2


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

* [iptables-nftables - RFC v2 PATCH  13/17] nft: Refactor rule deletion so it compares both cs structure
  2013-07-25 17:16 [iptables-nftables - RFC v2 PATCH 00/17] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
                   ` (11 preceding siblings ...)
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 12/17] nft: Refactor firewall printing so it reuses already parsed cs struct Tomasz Bursztyka
@ 2013-07-25 17:16 ` Tomasz Bursztyka
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 14/17] xtables: nft: Complete refactoring on how rules are saved Tomasz Bursztyka
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Tomasz Bursztyka @ 2013-07-25 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

Now that we parse properly, in one place and at once, the rule back into a 
command structure, it's now easier to compare the rule from that command
structure when deleting.


Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 iptables/nft.c | 197 +++++++++++----------------------------------------------
 1 file changed, 37 insertions(+), 160 deletions(-)

diff --git a/iptables/nft.c b/iptables/nft.c
index 2a0fa77..39dcc06 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -1830,187 +1830,64 @@ nft_rule_to_iptables_command_state(struct nft_rule *r,
 		i2cs.cs->jumpto = "";
 }
 
-static int matches_howmany(struct xtables_rule_match *matches)
-{
-	struct xtables_rule_match *matchp;
-	int matches_ctr = 0;
-
-	for (matchp = matches; matchp; matchp = matchp->next)
-		matches_ctr++;
-
-	return matches_ctr;
-}
-
 static bool
-__find_match(struct nft_rule_expr *expr, struct xtables_rule_match *matches)
+compare_matches(struct xtables_rule_match *matches_1,
+		struct xtables_rule_match *matches_2)
 {
-	const char *matchname = nft_rule_expr_get_str(expr, NFT_EXPR_MT_NAME);
-	/* Netlink aligns this match info, don't trust this length variable */
-	const char *data = nft_rule_expr_get_str(expr, NFT_EXPR_MT_INFO);
-	struct xtables_rule_match *matchp;
-	bool found = false;
-
-	for (matchp = matches; matchp; matchp = matchp->next) {
-		struct xt_entry_match *m = matchp->match->m;
+	struct xtables_rule_match *mp_1;
+	struct xtables_rule_match *mp_2;
+	for (mp_1 = matches_1, mp_2 = matches_2;
+			mp_1 && mp_2; mp_1 = mp_1->next, mp_2 = mp_2->next) {
+		struct xt_entry_match *m_1 = mp_1->match->m;
+		struct xt_entry_match *m_2 = mp_2->match->m;
 
-		if (strcmp(m->u.user.name, matchname) != 0) {
+		if (strcmp(m_1->u.user.name, m_2->u.user.name) != 0) {
 			DEBUGP("mismatching match name\n");
-			continue;
+			return false;
 		}
 
-		if (memcmp(data, m->data, m->u.user.match_size - sizeof(*m)) != 0) {
-			DEBUGP("mismatch match data\n");
-			continue;
+		if (m_1->u.user.match_size != m_2->u.user.match_size) {
+			DEBUGP("mismatching match size\n");
+			return false;
 		}
-		found = true;
-		break;
-	}
-
-	return found;
-}
-
-static bool find_matches(struct xtables_rule_match *matches, struct nft_rule *r)
-{
-	struct nft_rule_expr_iter *iter;
-	struct nft_rule_expr *expr;
-	int kernel_matches = 0;
 
-	iter = nft_rule_expr_iter_create(r);
-	if (iter == NULL)
-		return false;
-
-	expr = nft_rule_expr_iter_next(iter);
-	while (expr != NULL) {
-		const char *name =
-			nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME);
-
-		if (strcmp(name, "match") == 0) {
-			if (!__find_match(expr, matches))
-				return false;
-
-			kernel_matches++;
+		if (memcmp(m_1->data, m_2->data,
+				m_1->u.user.match_size - sizeof(*m_1)) != 0) {
+			DEBUGP("mismatch match data\n");
+			return false;
 		}
-		expr = nft_rule_expr_iter_next(iter);
 	}
-	nft_rule_expr_iter_destroy(iter);
-
-	/* same number of matches? */
-	if (matches_howmany(matches) != kernel_matches)
-		return false;
-
-	return true;
-}
 
-static bool __find_target(struct nft_rule_expr *expr, struct xt_entry_target *t)
-{
-	size_t len;
-	const char *tgname = nft_rule_expr_get_str(expr, NFT_EXPR_TG_NAME);
-	/* Netlink aligns this target info, don't trust this length variable */
-	const char *data = nft_rule_expr_get(expr, NFT_EXPR_TG_INFO, &len);
-
-	if (strcmp(t->u.user.name, tgname) != 0) {
-		DEBUGP("mismatching target name\n");
+	/* Both cursor should be NULL */
+	if (mp_1 != mp_2) {
+		DEBUGP("mismatch matches amount\n");
 		return false;
 	}
 
-	if (memcmp(data, t->data,  t->u.user.target_size - sizeof(*t)) != 0)
-		return false;
-
 	return true;
 }
 
-static int targets_howmany(struct xtables_target *target)
-{
-	return target != NULL ? 1 : 0;
-}
-
 static bool
-find_target(struct xtables_target *target, struct nft_rule *r)
+compare_targets(struct xtables_target *target_1,
+		struct xtables_target *target_2)
 {
-	struct nft_rule_expr_iter *iter;
-	struct nft_rule_expr *expr;
-	int kernel_targets = 0;
-
-	/* Special case: we use native immediate expressions to emulated
-	 * standard targets. Also, we don't want to crash with no targets.
-	 */
-	if (target == NULL || strcmp(target->name, "standard") == 0)
+	if (target_1 == NULL && target_2 == NULL)
 		return true;
 
-	iter = nft_rule_expr_iter_create(r);
-	if (iter == NULL)
+	if ((target_1 == NULL && target_2 != NULL) ||
+				(target_1 != NULL && target_2 == NULL))
 		return false;
 
-	expr = nft_rule_expr_iter_next(iter);
-	while (expr != NULL) {
-		const char *name =
-			nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME);
-
-		if (strcmp(name, "target") == 0) {
-			/* we may support several targets in the future */
-			if (!__find_target(expr, target->t))
-				return false;
-
-			kernel_targets++;
-		}
-		expr = nft_rule_expr_iter_next(iter);
-	}
-	nft_rule_expr_iter_destroy(iter);
-
-	/* same number of targets? */
-	if (targets_howmany(target) != kernel_targets) {
-		DEBUGP("kernel targets is %d but we passed %d\n",
-		kernel_targets, targets_howmany(target));
+	if (strcmp(target_1->t->u.user.name, target_2->t->u.user.name) != 0)
 		return false;
-	}
 
-	return true;
-}
-
-static bool
-find_immediate(struct nft_rule *r, const char *jumpto)
-{
-	struct nft_rule_expr_iter *iter;
-	struct nft_rule_expr *expr;
-
-	iter = nft_rule_expr_iter_create(r);
-	if (iter == NULL)
+	if (target_1->t->u.user.target_size != target_2->t->u.user.target_size)
 		return false;
 
-	expr = nft_rule_expr_iter_next(iter);
-	while (expr != NULL) {
-		const char *name =
-			nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME);
-
-		if (strcmp(name, "immediate") == 0) {
-			int verdict = nft_rule_expr_get_u32(expr, NFT_EXPR_IMM_VERDICT);
-			const char *verdict_name = NULL;
-
-			/* No target specified but immediate shows up, this
-			 * is not the rule we are looking for.
-			 */
-			if (strlen(jumpto) == 0)
-				return false;
-
-			switch(verdict) {
-			case NF_ACCEPT:
-				verdict_name = "ACCEPT";
-				break;
-			case NF_DROP:
-				verdict_name = "DROP";
-				break;
-			case NFT_RETURN:
-				verdict_name = "RETURN";
-				break;
-			}
-
-			/* Standard target? */
-			if (verdict_name && strcmp(jumpto, verdict_name) != 0)
-				return false;
-		}
-		expr = nft_rule_expr_iter_next(iter);
-	}
-	nft_rule_expr_iter_destroy(iter);
+	if (memcmp(target_1->t->data, target_2->t->data,
+					target_1->t->u.user.target_size -
+						sizeof(*target_1->t)) != 0)
+		return false;
 
 	return true;
 }
@@ -2090,18 +1967,18 @@ nft_rule_find(struct nft_rule_list *list, const char *chain, const char *table,
 			if (!ops->is_same(cs, &this))
 				goto next;
 
-			if (!find_matches(cs->matches, r)) {
-				DEBUGP("matches not found\n");
+			if (!compare_matches(cs->matches, this.matches)) {
+				DEBUGP("Different matches\n");
 				goto next;
 			}
 
-			if (!find_target(cs->target, r)) {
-				DEBUGP("target not found\n");
+			if (!compare_targets(cs->target, this.target)) {
+				DEBUGP("Different target\n");
 				goto next;
 			}
 
-			if (!find_immediate(r, cs->jumpto)) {
-				DEBUGP("immediate not found\n");
+			if (strcmp(cs->jumpto, this.jumpto) != 0) {
+				DEBUGP("Different verdict\n");
 				goto next;
 			}
 
-- 
1.8.3.2


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

* [iptables-nftables - RFC v2 PATCH  14/17] xtables: nft: Complete refactoring on how rules are saved
  2013-07-25 17:16 [iptables-nftables - RFC v2 PATCH 00/17] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
                   ` (12 preceding siblings ...)
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 13/17] nft: Refactor rule deletion so it compares both cs structure Tomasz Bursztyka
@ 2013-07-25 17:16 ` Tomasz Bursztyka
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 15/17] xtables: Support pure nft expressions for DNAT extension Tomasz Bursztyka
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: Tomasz Bursztyka @ 2013-07-25 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

Now that we parse properly, in one place and at once, the rule back into a 
command structure, it's now easier to save the rule from that command
structure.


Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 iptables/nft-ipv4.c       | 122 ++++++-------------
 iptables/nft-ipv6.c       |  72 +++++-------
 iptables/nft-shared.c     |  73 ++++++++++--
 iptables/nft-shared.h     |  13 ++-
 iptables/nft.c            | 290 +++++++---------------------------------------
 iptables/nft.h            |   8 +-
 iptables/xtables-events.c |  21 ++--
 7 files changed, 189 insertions(+), 410 deletions(-)

diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c
index 4b8f146..3c2a40f 100644
--- a/iptables/nft-ipv4.c
+++ b/iptables/nft-ipv4.c
@@ -97,50 +97,6 @@ static void get_frag_from_expr(struct nft_rule_expr *e, bool *inv)
 		*inv = false;
 }
 
-static void get_frag(struct nft_rule_expr_iter *iter, bool *inv)
-{
-	struct nft_rule_expr *e;
-	const char *name;
-	uint8_t op;
-
-	e = nft_rule_expr_iter_next(iter);
-	if (e == NULL)
-		return;
-
-	/* we assume correct mask and xor */
-	name = nft_rule_expr_get_str(e, NFT_RULE_EXPR_ATTR_NAME);
-	if (strcmp(name, "bitwise") != 0) {
-		DEBUGP("skipping no bitwise after payload\n");
-		return;
-	}
-
-	/* Now check for cmp */
-	e = nft_rule_expr_iter_next(iter);
-	if (e == NULL)
-		return;
-
-	/* we assume correct data */
-	name = nft_rule_expr_get_str(e, NFT_RULE_EXPR_ATTR_NAME);
-	if (strcmp(name, "cmp") != 0) {
-		DEBUGP("skipping no cmp after payload\n");
-		return;
-	}
-
-	op = nft_rule_expr_get_u8(e, NFT_EXPR_CMP_OP);
-	if (op == NFT_CMP_EQ)
-		*inv = true;
-	else
-		*inv = false;
-}
-
-static void print_frag(bool inv)
-{
-	if (inv)
-		printf("! -f ");
-	else
-		printf("-f ");
-}
-
 static const char *mask_to_str(uint32_t mask)
 {
 	static char mask_str[sizeof("255.255.255.255")];
@@ -167,50 +123,6 @@ static const char *mask_to_str(uint32_t mask)
 	return mask_str;
 }
 
-static void nft_ipv4_print_payload(struct nft_rule_expr *e,
-				  struct nft_rule_expr_iter *iter)
-{
-	uint32_t offset;
-	bool inv;
-
-	offset = nft_rule_expr_get_u32(e, NFT_EXPR_PAYLOAD_OFFSET);
-
-	switch(offset) {
-	struct in_addr addr;
-	uint8_t proto;
-
-	case offsetof(struct iphdr, saddr):
-		get_cmp_data(iter, &addr, sizeof(addr), &inv);
-		if (inv)
-			printf("! -s %s/%s ", inet_ntoa(addr),
-						mask_to_str(0xffffffff));
-		else
-			printf("-s %s/%s ", inet_ntoa(addr),
-						mask_to_str(0xffffffff));
-		break;
-	case offsetof(struct iphdr, daddr):
-		get_cmp_data(iter, &addr, sizeof(addr), &inv);
-		if (inv)
-			printf("! -d %s/%s ", inet_ntoa(addr),
-						mask_to_str(0xffffffff));
-		else
-			printf("-d %s/%s ", inet_ntoa(addr),
-						mask_to_str(0xffffffff));
-		break;
-	case offsetof(struct iphdr, protocol):
-		get_cmp_data(iter, &proto, sizeof(proto), &inv);
-		print_proto(proto, inv);
-		break;
-	case offsetof(struct iphdr, frag_off):
-		get_frag(iter, &inv);
-		print_frag(inv);
-		break;
-	default:
-		DEBUGP("unknown payload offset %d\n", offset);
-		break;
-	}
-}
-
 static void nft_ipv4_parse_meta(struct nft_rule_expr *e, uint8_t key,
 				struct iptables_command_state *cs)
 {
@@ -311,6 +223,38 @@ static uint8_t nft_ipv4_print_firewall(const struct iptables_command_state *cs,
 	return cs->fw.ip.flags;
 }
 
+static void save_ipv4_addr(char letter, const struct in_addr *addr,
+			   uint32_t mask, int invert)
+{
+	if (!mask && !invert && !addr->s_addr)
+		return;
+
+	printf("%s-%c %s/%s ", invert ? "! " : "", letter,
+			inet_ntoa(*addr), mask_to_str(mask));
+}
+
+static uint8_t nft_ipv4_save_firewall(const struct iptables_command_state *cs,
+				      unsigned int format)
+{
+	save_firewall_details(cs, cs->fw.ip.invflags, cs->fw.ip.proto,
+				cs->fw.ip.iniface, cs->fw.ip.iniface_mask,
+				cs->fw.ip.outiface, cs->fw.ip.outiface_mask,
+				format);
+
+	if (cs->fw.ip.flags & IPT_F_FRAG) {
+		if (cs->fw.ip.invflags & IPT_INV_FRAG)
+			printf("! ");
+		printf("-f ");
+	}
+
+	save_ipv4_addr('s', &cs->fw.ip.src, cs->fw.ip.smsk.s_addr,
+					cs->fw.ip.invflags & IPT_INV_SRCIP);
+	save_ipv4_addr('d', &cs->fw.ip.dst, cs->fw.ip.dmsk.s_addr,
+					cs->fw.ip.invflags & IPT_INV_DSTIP);
+
+	return cs->fw.ip.flags;
+}
+
 static void nft_ipv4_post_parse(int command,
 				struct iptables_command_state *cs,
 				struct xtables_args *args)
@@ -360,10 +304,10 @@ static void nft_ipv4_post_parse(int command,
 struct nft_family_ops nft_family_ops_ipv4 = {
 	.add			= nft_ipv4_add,
 	.is_same		= nft_ipv4_is_same,
-	.print_payload		= nft_ipv4_print_payload,
 	.parse_meta		= nft_ipv4_parse_meta,
 	.parse_payload		= nft_ipv4_parse_payload,
 	.parse_immediate	= nft_ipv4_parse_immediate,
 	.print_firewall		= nft_ipv4_print_firewall,
+	.save_firewall		= nft_ipv4_save_firewall,
 	.post_parse		= nft_ipv4_post_parse,
 };
diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c
index e5c8db9..138328f 100644
--- a/iptables/nft-ipv6.c
+++ b/iptables/nft-ipv6.c
@@ -69,48 +69,6 @@ static bool nft_ipv6_is_same(const struct iptables_command_state *a,
 				  b->fw6.ipv6.outiface_mask);
 }
 
-static void nft_ipv6_print_payload(struct nft_rule_expr *e,
-				   struct nft_rule_expr_iter *iter)
-{
-	uint32_t offset;
-	bool inv;
-
-	offset = nft_rule_expr_get_u32(e, NFT_EXPR_PAYLOAD_OFFSET);
-
-	switch (offset) {
-	char addr_str[INET6_ADDRSTRLEN];
-	struct in6_addr addr;
-	uint8_t proto;
-	case offsetof(struct ip6_hdr, ip6_src):
-		get_cmp_data(iter, &addr, sizeof(addr), &inv);
-		inet_ntop(AF_INET6, &addr, addr_str, INET6_ADDRSTRLEN);
-
-		if (inv)
-			printf("! -s %s ", addr_str);
-		else
-			printf("-s %s ", addr_str);
-
-		break;
-	case offsetof(struct ip6_hdr, ip6_dst):
-		get_cmp_data(iter, &addr, sizeof(addr), &inv);
-		inet_ntop(AF_INET6, &addr, addr_str, INET6_ADDRSTRLEN);
-
-		if (inv)
-			printf("! -d %s ", addr_str);
-		else
-			printf("-d %s ", addr_str);
-
-		break;
-	case offsetof(struct ip6_hdr, ip6_nxt):
-		get_cmp_data(iter, &proto, sizeof(proto), &inv);
-		print_proto(proto, inv);
-		break;
-	default:
-		DEBUGP("unknown payload offset %d\n", offset);
-		break;
-	}
-}
-
 static void nft_ipv6_parse_meta(struct nft_rule_expr *e, uint8_t key,
 				struct iptables_command_state *cs)
 {
@@ -209,6 +167,34 @@ static uint8_t nft_ipv6_print_firewall(const struct iptables_command_state *cs,
 	return cs->fw6.ipv6.flags;
 }
 
+static void save_ipv6_addr(char letter, const struct in6_addr *addr,
+			   int invert)
+{
+	char addr_str[INET6_ADDRSTRLEN];
+
+	if (!invert && !IN6_IS_ADDR_UNSPECIFIED(addr))
+		return;
+
+	inet_ntop(AF_INET6, &addr, addr_str, INET6_ADDRSTRLEN);
+	printf("%s-%c %s ", invert ? "! " : "", letter, addr_str);
+}
+
+static uint8_t nft_ipv6_save_firewall(const struct iptables_command_state *cs,
+				      unsigned int format)
+{
+	save_firewall_details(cs, cs->fw6.ipv6.invflags, cs->fw6.ipv6.proto,
+			cs->fw6.ipv6.iniface, cs->fw6.ipv6.iniface_mask,
+			cs->fw6.ipv6.outiface, cs->fw6.ipv6.outiface_mask,
+			format);
+
+	save_ipv6_addr('s', &cs->fw6.ipv6.src,
+				cs->fw6.ipv6.invflags & IPT_INV_SRCIP);
+	save_ipv6_addr('d', &cs->fw6.ipv6.dst,
+				cs->fw6.ipv6.invflags & IPT_INV_DSTIP);
+
+	return cs->fw6.ipv6.flags;
+}
+
 /* These are invalid numbers as upper layer protocol */
 static int is_exthdr(uint16_t proto)
 {
@@ -278,10 +264,10 @@ static void nft_ipv6_post_parse(int command, struct iptables_command_state *cs,
 struct nft_family_ops nft_family_ops_ipv6 = {
 	.add			= nft_ipv6_add,
 	.is_same		= nft_ipv6_is_same,
-	.print_payload		= nft_ipv6_print_payload,
 	.parse_meta		= nft_ipv6_parse_meta,
 	.parse_payload		= nft_ipv6_parse_payload,
 	.parse_immediate	= nft_ipv6_parse_immediate,
 	.print_firewall		= nft_ipv6_print_firewall,
+	.save_firewall		= nft_ipv6_save_firewall,
 	.post_parse		= nft_ipv6_post_parse,
 };
diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c
index 99a7681..9d25b98 100644
--- a/iptables/nft-shared.c
+++ b/iptables/nft-shared.c
@@ -313,18 +313,6 @@ void get_expr_cmp_data(struct nft_rule_expr *e,
 		*inv = false;
 }
 
-void get_cmp_data(struct nft_rule_expr_iter *iter,
-		  void *data, size_t dlen, bool *inv)
-{
-	struct nft_rule_expr *e;
-
-	e = nft_rule_expr_iter_next(iter);
-	if (e == NULL)
-		return;
-
-	get_expr_cmp_data(e, data, dlen, inv);
-}
-
 void print_num(uint64_t number, unsigned int format)
 {
 	if (format & FMT_KILOMEGAGIGA) {
@@ -414,6 +402,67 @@ void print_firewall_details(const struct iptables_command_state *cs,
 	}
 }
 
+static void
+print_iface(char letter, const char *iface, const unsigned char *mask,
+            int invert)
+{
+	unsigned int i;
+
+	if (mask[0] == 0)
+		return;
+
+	printf("%s-%c ", invert ? "! " : "", letter);
+
+	for (i = 0; i < IFNAMSIZ; i++) {
+		if (mask[i] != 0) {
+			if (iface[i] != '\0')
+				printf("%c", iface[i]);
+			} else {
+				if (iface[i-1] != '\0')
+					printf("+");
+				break;
+		}
+	}
+
+	printf(" ");
+}
+
+void save_firewall_details(const struct iptables_command_state *cs,
+			   uint8_t invflags, uint16_t proto,
+			   const char *iniface,
+			   unsigned const char *iniface_mask,
+			   const char *outiface,
+			   unsigned const char *outiface_mask,
+			   unsigned int format)
+{
+	if (!(format & FMT_NOCOUNTS)) {
+		printf("-c ");
+		print_num(cs->counters.pcnt, format);
+		print_num(cs->counters.bcnt, format);
+	}
+
+	if (iniface != NULL)
+		print_iface('i', iniface, iniface_mask,
+					invflags & IPT_INV_VIA_IN);
+
+	if (outiface != NULL)
+		print_iface('o', outiface, outiface_mask,
+					invflags & IPT_INV_VIA_OUT);
+
+	if (proto > 0) {
+		const struct protoent *pent = getprotobynumber(proto);
+
+		if (invflags & XT_INV_PROTO)
+			printf("! ");
+
+		if (pent)
+			printf("-p %s ", pent->p_name);
+		else
+			printf("-p %u ", proto);
+	}
+
+}
+
 struct nft_family_ops *nft_family_ops_lookup(int family)
 {
 	switch (family) {
diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h
index 2c199b4..45eccf5 100644
--- a/iptables/nft-shared.h
+++ b/iptables/nft-shared.h
@@ -40,8 +40,6 @@ struct nft_family_ops {
 	int (*add)(struct nft_rule *r, struct iptables_command_state *cs);
 	bool (*is_same)(const struct iptables_command_state *a,
 			const struct iptables_command_state *b);
-	void (*print_payload)(struct nft_rule_expr *e,
-			      struct nft_rule_expr_iter *iter);
 	void (*parse_meta)(struct nft_rule_expr *e, uint8_t key,
 			   struct iptables_command_state *cs);
 	void (*parse_payload)(struct nft_rule_expr *e_1,
@@ -52,6 +50,8 @@ struct nft_family_ops {
 	uint8_t (*print_firewall)(const struct iptables_command_state *cs,
 				  const char *targname, unsigned int num,
 				  unsigned int format);
+	uint8_t (*save_firewall)(const struct iptables_command_state *cs,
+				 unsigned int format);
 	void (*post_parse)(int command, struct iptables_command_state *cs,
 			   struct xtables_args *args);
 };
@@ -85,14 +85,19 @@ void parse_meta(struct nft_rule_expr *e, uint8_t key, char *iniface,
 void print_proto(uint16_t proto, int invert);
 void get_expr_cmp_data(struct nft_rule_expr *e,
 		       void *data, size_t dlen, bool *inv);
-void get_cmp_data(struct nft_rule_expr_iter *iter,
-		  void *data, size_t dlen, bool *inv);
 void print_num(uint64_t number, unsigned int format);
 void print_firewall_details(const struct iptables_command_state *cs,
 			    const char *targname, uint8_t flags,
 			    uint8_t invflags, uint8_t proto,
 			    const char *iniface, const char *outiface,
 			    unsigned int num, unsigned int format);
+void save_firewall_details(const struct iptables_command_state *cs,
+			   uint8_t invflags, uint16_t proto,
+			   const char *iniface,
+			   unsigned const char *iniface_mask,
+			   const char *outiface,
+			   unsigned const char *outiface_mask,
+			   unsigned int format);
 
 struct nft_family_ops *nft_family_ops_lookup(int family);
 
diff --git a/iptables/nft.c b/iptables/nft.c
index 39dcc06..d05f6ae 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -53,8 +53,6 @@
 #include "xtables-config-parser.h"
 #include "nft-xt-ext.h"
 
-static void initiate_nft_translation_tree(void);
-
 static void *nft_fn;
 struct nft_trans_instruction_tree *xt_nft_tree;
 
@@ -408,7 +406,7 @@ int nft_init(struct nft_handle *h)
 	}
 	h->portid = mnl_socket_get_portid(h->nl);
 
-	initiate_nft_translation_tree();
+	nft_initiate_translation_tree();
 
 	return 0;
 }
@@ -812,224 +810,27 @@ err:
 	return ret == 0 ? 1 : 0;
 }
 
-static void nft_match_save(struct nft_rule_expr *expr)
-{
-	const char *name;
-	const struct xtables_match *match;
-	struct xt_entry_match *emu;
-	const void *mtinfo;
-	size_t len;
-
-	name = nft_rule_expr_get_str(expr, NFT_EXPR_MT_NAME);
-
-	match = xtables_find_match(name, XTF_TRY_LOAD, NULL);
-	if (match == NULL)
-		return;
-
-	mtinfo = nft_rule_expr_get(expr, NFT_EXPR_MT_INFO, &len);
-	if (mtinfo == NULL)
-		return;
-
-	emu = calloc(1, sizeof(struct xt_entry_match) + len);
-	if (emu == NULL)
-		return;
-
-	memcpy(&emu->data, mtinfo, len);
-
-	if (match->alias)
-		printf("-m %s", match->alias(emu));
-	else
-		printf("-m %s", match->name);
-
-	/* FIXME missing parameter */
-	if (match->save)
-		match->save(NULL, emu);
-
-	printf(" ");
-
-	free(emu);
-}
-
-static void nft_target_save(struct nft_rule_expr *expr)
-{
-	const char *name;
-	const struct xtables_target *target;
-	struct xt_entry_target *emu;
-	const void *tginfo;
-	size_t len;
-
-	name = nft_rule_expr_get_str(expr, NFT_EXPR_TG_NAME);
-
-	/* Standard target not supported, we use native immediate expression */
-	if (strcmp(name, "") == 0) {
-		printf("ERROR: standard target seen, should not happen\n");
-		return;
-	}
-
-	target = xtables_find_target(name, XTF_TRY_LOAD);
-	if (target == NULL)
-		return;
-
-	tginfo = nft_rule_expr_get(expr, NFT_EXPR_TG_INFO, &len);
-	if (tginfo == NULL)
-		return;
-
-	emu = calloc(1, sizeof(struct xt_entry_match) + len);
-	if (emu == NULL)
-		return;
-
-	memcpy(emu->data, tginfo, len);
-
-	if (target->alias)
-		printf("-j %s", target->alias(emu));
-	else
-		printf("-j %s", target->name);
-
-	/* FIXME missing parameter */
-	if (target->save)
-		target->save(NULL, emu);
-
-	free(emu);
-}
-
-static void nft_immediate_save(struct nft_rule_expr *expr)
-{
-	uint32_t verdict;
-
-	verdict = nft_rule_expr_get_u32(expr, NFT_EXPR_IMM_VERDICT);
-
-	switch(verdict) {
-	case NF_ACCEPT:
-		printf("-j ACCEPT");
-		break;
-	case NF_DROP:
-		printf("-j DROP");
-		break;
-	case NFT_RETURN:
-		printf("-j RETURN");
-		break;
-	case NFT_GOTO:
-		printf("-g %s",
-			nft_rule_expr_get_str(expr, NFT_EXPR_IMM_CHAIN));
-		break;
-	case NFT_JUMP:
-		printf("-j %s",
-			nft_rule_expr_get_str(expr, NFT_EXPR_IMM_CHAIN));
-		break;
-	}
-}
-
-static void
-nft_print_meta(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter)
+void
+nft_rule_print_save(const struct iptables_command_state *cs,
+		    struct nft_rule *r, enum nft_rule_print type,
+		    unsigned int format)
 {
-	uint8_t key = nft_rule_expr_get_u8(e, NFT_EXPR_META_KEY);
-	uint32_t value;
-	const char *name;
-	char ifname[IFNAMSIZ];
-	const char *ifname_ptr;
-	size_t len;
-
-	e = nft_rule_expr_iter_next(iter);
-	if (e == NULL)
-		return;
-
-	name = nft_rule_expr_get_str(e, NFT_RULE_EXPR_ATTR_NAME);
-	/* meta should be followed by cmp */
-	if (strcmp(name, "cmp") != 0) {
-		DEBUGP("skipping no cmp after meta\n");
-		return;
-	}
-
-	switch(key) {
-	case NFT_META_IIF:
-		value = nft_rule_expr_get_u32(e, NFT_EXPR_CMP_DATA);
-		if_indextoname(value, ifname);
-
-		switch(nft_rule_expr_get_u8(e, NFT_EXPR_CMP_OP)) {
-		case NFT_CMP_EQ:
-			printf("-i %s ", ifname);
-			break;
-		case NFT_CMP_NEQ:
-			printf("! -i %s ", ifname);
-			break;
-		}
-		break;
-	case NFT_META_OIF:
-		value = nft_rule_expr_get_u32(e, NFT_EXPR_CMP_DATA);
-		if_indextoname(value, ifname);
-
-		switch(nft_rule_expr_get_u8(e, NFT_EXPR_CMP_OP)) {
-		case NFT_CMP_EQ:
-			printf("-o %s ", ifname);
-			break;
-		case NFT_CMP_NEQ:
-			printf("! -o %s ", ifname);
-			break;
-		}
-		break;
-	case NFT_META_IIFNAME:
-		ifname_ptr = nft_rule_expr_get(e, NFT_EXPR_CMP_DATA, &len);
-		memcpy(ifname, ifname_ptr, len);
-		ifname[len] = '\0';
-
-		/* if this is zero, then assume this is a interface mask */
-		if (if_nametoindex(ifname) == 0) {
-			ifname[len] = '+';
-			ifname[len+1] = '\0';
-		}
+	const char *chain = nft_rule_attr_get_str(r, NFT_RULE_ATTR_CHAIN);
+	int family = nft_rule_attr_get_u8(r, NFT_RULE_ATTR_FAMILY);
+	struct xtables_rule_match *matchp;
+	struct nft_family_ops *ops;
+	int ip_flags = 0;
 
-		switch(nft_rule_expr_get_u8(e, NFT_EXPR_CMP_OP)) {
-		case NFT_CMP_EQ:
-			printf("-i %s ", ifname);
-			break;
-		case NFT_CMP_NEQ:
-			printf("! -i %s ", ifname);
-			break;
-		}
+	switch(family) {
+	case AF_INET:
+		printf("-4 ");
 		break;
-	case NFT_META_OIFNAME:
-		ifname_ptr = nft_rule_expr_get(e, NFT_EXPR_CMP_DATA, &len);
-		memcpy(ifname, ifname_ptr, len);
-		ifname[len] = '\0';
-
-		/* if this is zero, then assume this is a interface mask */
-		if (if_nametoindex(ifname) == 0) {
-			ifname[len] = '+';
-			ifname[len+1] = '\0';
-		}
-
-		switch(nft_rule_expr_get_u8(e, NFT_EXPR_CMP_OP)) {
-		case NFT_CMP_EQ:
-			printf("-o %s ", ifname);
-			break;
-		case NFT_CMP_NEQ:
-			printf("! -o %s ", ifname);
-			break;
-		}
+	case AF_INET6:
+		printf("-6 ");
 		break;
 	default:
-		DEBUGP("unknown meta key %d\n", key);
 		break;
 	}
-}
-
-static void
-nft_print_counters(struct nft_rule_expr *e, struct nft_rule_expr_iter *iter,
-		   bool counters)
-{
-	if (counters) {
-		printf("-c %"PRIu64" %"PRIu64" ",
-			nft_rule_expr_get_u64(e, NFT_EXPR_CTR_PACKETS),
-			nft_rule_expr_get_u64(e, NFT_EXPR_CTR_BYTES));
-	}
-}
-
-void
-nft_rule_print_save(struct nft_rule *r, enum nft_rule_print type, bool counters)
-{
-	struct nft_rule_expr_iter *iter;
-	struct nft_rule_expr *expr;
-	const char *chain = nft_rule_attr_get_str(r, NFT_RULE_ATTR_CHAIN);
 
 	/* print chain name */
 	switch(type) {
@@ -1041,33 +842,24 @@ nft_rule_print_save(struct nft_rule *r, enum nft_rule_print type, bool counters)
 		break;
 	}
 
-	iter = nft_rule_expr_iter_create(r);
-	if (iter == NULL)
-		return;
+	ops = nft_family_ops_lookup(family);
+	ip_flags = ops->save_firewall(cs, format);
 
-	expr = nft_rule_expr_iter_next(iter);
-	while (expr != NULL) {
-		const char *name =
-			nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME);
+	for (matchp = cs->matches; matchp; matchp = matchp->next) {
+		printf("-m %s", matchp->match->name);
+		if (matchp->match->save != NULL)
+			matchp->match->save(NULL, matchp->match->m);
+		printf(" ");
+	}
 
-		if (strcmp(name, "counter") == 0) {
-			nft_print_counters(expr, iter, counters);
-		} else if (strcmp(name, "payload") == 0) {
-			struct nft_family_ops *ops = nft_family_ops_lookup(
-				nft_rule_attr_get_u8(r, NFT_RULE_ATTR_FAMILY));
-			ops->print_payload(expr, iter);
-		} else if (strcmp(name, "meta") == 0) {
-			nft_print_meta(expr, iter);
-		} else if (strcmp(name, "match") == 0) {
-			nft_match_save(expr);
-		} else if (strcmp(name, "target") == 0) {
-			nft_target_save(expr);
-		} else if (strcmp(name, "immediate") == 0) {
-			nft_immediate_save(expr);
-		}
+	if (cs->target != NULL) {
+		printf("-j %s", cs->jumpto);
 
-		expr = nft_rule_expr_iter_next(iter);
-	}
+		if (cs->target->save != NULL)
+			cs->target->save(NULL, cs->target->t);
+	} else if (strlen(cs->jumpto) > 0)
+		printf("-%c %s", ip_flags & IPT_F_GOTO ? 'g' : 'j',
+								cs->jumpto);
 
 	printf("\n");
 }
@@ -1249,11 +1041,15 @@ int nft_rule_save(struct nft_handle *h, const char *table, bool counters)
 	while (r != NULL) {
 		const char *rule_table =
 			nft_rule_attr_get_str(r, NFT_RULE_ATTR_TABLE);
+		struct iptables_command_state cs = {};
 
 		if (strcmp(table, rule_table) != 0)
 			goto next;
 
-		nft_rule_print_save(r, NFT_RULE_APPEND, counters);
+		nft_rule_to_iptables_command_state(r, &cs);
+
+		nft_rule_print_save(&cs, r, NFT_RULE_APPEND,
+						counters ? 0 : FMT_NOCOUNTS);
 
 next:
 		r = nft_rule_list_iter_next(iter);
@@ -1809,9 +1605,8 @@ static int nft_parse_ip_addresses(struct nft_trans_rule_context *rule_ctx,
 	return 0;
 }
 
-static void
-nft_rule_to_iptables_command_state(struct nft_rule *r,
-				   struct iptables_command_state *cs)
+void nft_rule_to_iptables_command_state(struct nft_rule *r,
+					struct iptables_command_state *cs)
 {
 	struct nft_to_cs_data i2cs = {};
 
@@ -1957,13 +1752,12 @@ nft_rule_find(struct nft_rule_list *list, const char *chain, const char *table,
 			break;
 		} else {
 			/* Delete by matching rule case */
+			nft_rule_to_iptables_command_state(r, &this);
+
 			DEBUGP("comparing with... ");
 #ifdef DEBUG_DEL
-			nft_rule_print_save(r, NFT_RULE_APPEND, 0);
+			nft_rule_print_save(&this, r, NFT_RULE_APPEND, 0);
 #endif
-
-			nft_rule_to_iptables_command_state(r, &this);
-
 			if (!ops->is_same(cs, &this))
 				goto next;
 
@@ -2406,7 +2200,7 @@ static void
 list_save(const struct iptables_command_state *cs, struct nft_rule *r,
 	  unsigned int num, unsigned int format)
 {
-	nft_rule_print_save(r, NFT_RULE_APPEND, !(format & FMT_NOCOUNTS));
+	nft_rule_print_save(cs, r, NFT_RULE_APPEND, format);
 }
 
 static int
@@ -2710,7 +2504,7 @@ static struct nft_trans_instruction nft_ipt_ip_addr_2 = {
 	.function = nft_parse_ip_addresses,
 };
 
-static void initiate_nft_translation_tree(void)
+void nft_initiate_translation_tree(void)
 {
 	xt_nft_tree = nft_trans_instruction_tree_new();
 	if (xt_nft_tree == NULL)
diff --git a/iptables/nft.h b/iptables/nft.h
index 7a6351b..c904e21 100644
--- a/iptables/nft.h
+++ b/iptables/nft.h
@@ -65,7 +65,13 @@ enum nft_rule_print {
 	NFT_RULE_DEL,
 };
 
-void nft_rule_print_save(struct nft_rule *r, enum nft_rule_print type, bool counters);
+void nft_initiate_translation_tree(void);
+void
+nft_rule_to_iptables_command_state(struct nft_rule *r,
+				   struct iptables_command_state *cs);
+void nft_rule_print_save(const struct iptables_command_state *cs,
+			 struct nft_rule *r, enum nft_rule_print type,
+			 unsigned int format);
 
 /*
  * global commit and abort
diff --git a/iptables/xtables-events.c b/iptables/xtables-events.c
index 64ae972..220a28e 100644
--- a/iptables/xtables-events.c
+++ b/iptables/xtables-events.c
@@ -58,6 +58,7 @@ static bool counters;
 
 static int rule_cb(const struct nlmsghdr *nlh, int type)
 {
+	struct iptables_command_state cs = {};
 	struct nft_rule *r;
 
 	r = nft_rule_alloc();
@@ -71,20 +72,12 @@ static int rule_cb(const struct nlmsghdr *nlh, int type)
 		goto err_free;
 	}
 
-	switch(nft_rule_attr_get_u8(r, NFT_RULE_ATTR_FAMILY)) {
-	case AF_INET:
-		printf("-4 ");
-		break;
-	case AF_INET6:
-		printf("-6 ");
-		break;
-	default:
-		break;
-	}
+	nft_rule_to_iptables_command_state(r, &cs);
 
-	nft_rule_print_save(r, type == NFT_MSG_NEWRULE ? NFT_RULE_APPEND :
-							 NFT_RULE_DEL,
-			    counters);
+	nft_rule_print_save(&cs, r,
+				type == NFT_MSG_NEWRULE ?
+					NFT_RULE_APPEND : NFT_RULE_DEL,
+				counters ? 0 : FMT_NOCOUNTS);
 err_free:
 	nft_rule_free(r);
 err:
@@ -195,6 +188,8 @@ int xtables_events_main(int argc, char *argv[])
 		exit(EXIT_FAILURE);
 	}
 
+	nft_initiate_translation_tree();
+
 	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
 	while (ret > 0) {
 		ret = mnl_cb_run(buf, ret, 0, 0, events_cb, NULL);
-- 
1.8.3.2


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

* [iptables-nftables - RFC v2 PATCH  15/17] xtables: Support pure nft expressions for DNAT extension
  2013-07-25 17:16 [iptables-nftables - RFC v2 PATCH 00/17] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
                   ` (13 preceding siblings ...)
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 14/17] xtables: nft: Complete refactoring on how rules are saved Tomasz Bursztyka
@ 2013-07-25 17:16 ` Tomasz Bursztyka
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 16/17] nft: Add a function to reset the counters of an existing rule Tomasz Bursztyka
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 17/17] xtables: Support -Z options for a given rule number Tomasz Bursztyka
  16 siblings, 0 replies; 18+ messages in thread
From: Tomasz Bursztyka @ 2013-07-25 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

Add the support for DNAT xtables extensions to be expressed directly into
pure nft expression and not more via the compatible expression "target".
Provide also the function to register the different pattern of such
extension when expressed purely in nft so it can be parsed back, and the
memory blob can be recreated. Given callback from the core will then
feed the command structure relevantly.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 extensions/libipt_DNAT.c | 221 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 221 insertions(+)

diff --git a/extensions/libipt_DNAT.c b/extensions/libipt_DNAT.c
index ff18799..f6f0769 100644
--- a/extensions/libipt_DNAT.c
+++ b/extensions/libipt_DNAT.c
@@ -7,6 +7,7 @@
 #include <limits.h> /* INT_MAX in ip_tables.h */
 #include <linux/netfilter_ipv4/ip_tables.h>
 #include <linux/netfilter/nf_nat.h>
+#include <linux/netfilter/nf_tables.h>
 
 enum {
 	O_TO_DEST = 0,
@@ -242,6 +243,224 @@ static void DNAT_save(const void *ip, const struct xt_entry_target *target)
 	}
 }
 
+static struct nft_rule_expr *
+add_nat_data(struct nft_rule *rule, int reg, uint32_t data)
+{
+	struct nft_rule_expr *expr;
+
+	expr = nft_rule_expr_alloc("immediate");
+	if (expr == NULL)
+		return NULL;
+
+	nft_rule_expr_set_u32(expr, NFT_EXPR_IMM_DREG, reg);
+	nft_rule_expr_set_u32(expr, NFT_EXPR_IMM_DATA, data);
+
+	nft_rule_add_expr(rule, expr);
+
+	return expr;
+}
+
+static int add_nat_expr(struct nft_rule *rule,
+			const struct nf_nat_ipv4_range *r)
+{
+	struct nft_rule_expr *nat_expr;
+	int registers = 1;
+
+	nat_expr = nft_rule_expr_alloc("nat");
+	if (nat_expr == NULL)
+		return -1;
+
+	nft_rule_expr_set_u32(nat_expr, NFT_EXPR_NAT_TYPE, NFT_NAT_DNAT);
+	nft_rule_expr_set_u32(nat_expr, NFT_EXPR_NAT_FAMILY, AF_INET);
+
+	if (r->flags & NF_NAT_RANGE_MAP_IPS) {
+		nft_rule_expr_set_u32(nat_expr, NFT_EXPR_NAT_REG_ADDR_MIN,
+				      registers);
+		if (add_nat_data(rule, registers, r->min_ip) == NULL)
+			goto error;
+		registers++;
+
+		if (r->max_ip != r->min_ip) {
+			nft_rule_expr_set_u32(nat_expr,
+					      NFT_EXPR_NAT_REG_ADDR_MAX,
+					      registers);
+			if (add_nat_data(rule, registers, r->max_ip) == NULL)
+				goto error;
+			registers++;
+		}
+	}
+
+	if (r->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
+		nft_rule_expr_set_u32(nat_expr, NFT_EXPR_NAT_REG_PROTO_MIN,
+				      registers);
+		if (add_nat_data(rule, registers,
+					ntohs(r->min.tcp.port)) == NULL)
+			goto error;
+		registers++;
+
+		if (r->max.tcp.port != r->min.tcp.port) {
+			nft_rule_expr_set_u32(nat_expr,
+					      NFT_EXPR_NAT_REG_PROTO_MAX,
+					      registers);
+			if (add_nat_data(rule, registers,
+					ntohs(r->max.tcp.port)) == NULL)
+				goto error;
+		}
+	}
+
+	nft_rule_add_expr(rule, nat_expr);
+
+	return 0;
+
+error:
+	nft_rule_expr_free(nat_expr);
+	return -1;
+}
+
+static int DNAT_to_nft(struct nft_rule *rule, struct xt_entry_target *target)
+{
+	const struct ipt_natinfo *info = (const void *)target;
+	int i;
+
+	for (i = 0; i < info->mr.rangesize; i++) {
+		if (add_nat_expr(rule, &info->mr.range[i]) < 0)
+			return -1;
+	}
+
+	return 0;
+}
+
+static inline void get_nat_port(struct nft_rule_expr *expr, uint16_t *data)
+{
+	uint32_t value;
+
+	value = nft_rule_expr_get_u32(expr, NFT_EXPR_IMM_DATA);
+	*data = htons((uint16_t) value);
+}
+
+static int DNAT_parse_nft(struct nft_trans_rule_context *rule_ctx,
+			  struct nft_trans_instruction_context *first,
+			  struct nft_trans_instruction_context *last,
+			  nft_trans_parse_callback_f user_cb,
+			  void *user_data)
+{
+	struct nft_rule_expr *e_nat, *e;
+	struct nf_nat_ipv4_range range;
+	struct ipt_natinfo *info;
+	uint32_t type, reg;
+
+	if (user_cb == NULL)
+		return -1;
+
+	e_nat = nft_trans_instruction_context_get_expr(last);
+
+	if (!nft_rule_expr_is_set(e_nat, NFT_EXPR_NAT_TYPE))
+		return -1;
+
+	type = nft_rule_expr_get_u32(e_nat, NFT_EXPR_NAT_TYPE);
+	if (type != NFT_NAT_DNAT)
+		return -1;
+
+	if (nft_rule_expr_is_set(e_nat, NFT_EXPR_NAT_REG_ADDR_MIN)) {
+		range.flags |= NF_NAT_RANGE_MAP_IPS;
+
+		reg = nft_rule_expr_get_u32(e_nat, NFT_EXPR_NAT_REG_ADDR_MIN);
+		e = nft_trans_instruction_context_get_register(last, reg);
+		range.min_ip = nft_rule_expr_get_u32(e, NFT_EXPR_IMM_DATA);
+
+		if (nft_rule_expr_is_set(e_nat,	NFT_EXPR_NAT_REG_ADDR_MAX)) {
+			reg = nft_rule_expr_get_u32(e_nat,
+						NFT_EXPR_NAT_REG_ADDR_MAX);
+			e = nft_trans_instruction_context_get_register(last, reg);
+			range.max_ip = nft_rule_expr_get_u32(e,
+							NFT_EXPR_IMM_DATA);
+		} else
+			range.max_ip = range.min_ip;
+	}
+
+	if (nft_rule_expr_is_set(e_nat, NFT_EXPR_NAT_REG_PROTO_MIN)) {
+		range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
+
+		reg = nft_rule_expr_get_u32(e_nat, NFT_EXPR_NAT_REG_PROTO_MIN);
+		e = nft_trans_instruction_context_get_register(last, reg);
+		get_nat_port(e, &range.min.tcp.port);
+
+		if (nft_rule_expr_is_set(e_nat, NFT_EXPR_NAT_REG_PROTO_MAX)) {
+			reg = nft_rule_expr_get_u32(e_nat,
+						NFT_EXPR_NAT_REG_PROTO_MAX);
+			e = nft_trans_instruction_context_get_register(last, reg);
+			get_nat_port(e, &range.max.tcp.port);
+		} else
+			range.max.tcp.port = range.min.tcp.port;
+	}
+
+	info = calloc(1, sizeof(struct ipt_natinfo));
+	if (info == NULL)
+		return -1;
+
+	info = append_range(NULL, &range);
+	if (user_cb("DNAT", &info->t, user_data) != 0) {
+		free(info);
+		return -1;
+	}
+
+	return 0;
+}
+
+static enum nft_instruction xt_dnat_instructions_1[] = {
+	NFT_INSTRUCTION_IMMEDIATE, NFT_INSTRUCTION_NAT,
+	NFT_INSTRUCTION_MAX,
+};
+
+static struct nft_trans_instruction xt_dnat_1 = {
+	.instructions = xt_dnat_instructions_1,
+	.function = DNAT_parse_nft,
+};
+
+static enum nft_instruction xt_dnat_instructions_2[] = {
+	NFT_INSTRUCTION_IMMEDIATE, NFT_INSTRUCTION_IMMEDIATE,
+	NFT_INSTRUCTION_NAT,
+	NFT_INSTRUCTION_MAX,
+};
+
+static struct nft_trans_instruction xt_dnat_2 = {
+	.instructions = xt_dnat_instructions_2,
+	.function = DNAT_parse_nft,
+};
+
+static enum nft_instruction xt_dnat_instructions_3[] = {
+	NFT_INSTRUCTION_IMMEDIATE, NFT_INSTRUCTION_IMMEDIATE,
+	NFT_INSTRUCTION_IMMEDIATE, NFT_INSTRUCTION_NAT,
+	NFT_INSTRUCTION_MAX,
+};
+
+static struct nft_trans_instruction xt_dnat_3 = {
+	.instructions = xt_dnat_instructions_3,
+	.function = DNAT_parse_nft,
+};
+
+static enum nft_instruction xt_dnat_instructions_4[] = {
+	NFT_INSTRUCTION_IMMEDIATE, NFT_INSTRUCTION_IMMEDIATE,
+	NFT_INSTRUCTION_IMMEDIATE, NFT_INSTRUCTION_IMMEDIATE,
+	NFT_INSTRUCTION_NAT,
+	NFT_INSTRUCTION_MAX,
+};
+
+static struct nft_trans_instruction xt_dnat_4 = {
+	.instructions = xt_dnat_instructions_4,
+	.function = DNAT_parse_nft,
+};
+
+static int DNAT_register_nft_instructions(struct nft_trans_instruction_tree *tree)
+{
+	nft_trans_add_instruction(tree, &xt_dnat_1);
+	nft_trans_add_instruction(tree, &xt_dnat_2);
+	nft_trans_add_instruction(tree, &xt_dnat_3);
+	nft_trans_add_instruction(tree, &xt_dnat_4);
+
+	return 0;
+}
+
 static struct xtables_target dnat_tg_reg = {
 	.name		= "DNAT",
 	.version	= XTABLES_VERSION,
@@ -254,6 +473,8 @@ static struct xtables_target dnat_tg_reg = {
 	.print		= DNAT_print,
 	.save		= DNAT_save,
 	.x6_options	= DNAT_opts,
+	.to_nft		= DNAT_to_nft,
+	.register_nft_instructions = DNAT_register_nft_instructions,
 };
 
 void _init(void)
-- 
1.8.3.2


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

* [iptables-nftables - RFC v2 PATCH  16/17] nft: Add a function to reset the counters of an existing rule
  2013-07-25 17:16 [iptables-nftables - RFC v2 PATCH 00/17] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
                   ` (14 preceding siblings ...)
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 15/17] xtables: Support pure nft expressions for DNAT extension Tomasz Bursztyka
@ 2013-07-25 17:16 ` Tomasz Bursztyka
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 17/17] xtables: Support -Z options for a given rule number Tomasz Bursztyka
  16 siblings, 0 replies; 18+ messages in thread
From: Tomasz Bursztyka @ 2013-07-25 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

Now that we parse properly, in one place and at once, the rule back into a 
command structure, it's now easier to reset its counters from that command
structure which we can pass again to nft_rule_append. (Thus the rule will
be replaced since we provide it's handle.)


Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 iptables/nft.c | 35 +++++++++++++++++++++++++++++++++++
 iptables/nft.h |  1 +
 2 files changed, 36 insertions(+)

diff --git a/iptables/nft.c b/iptables/nft.c
index d05f6ae..2b17e37 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -2298,6 +2298,41 @@ err:
 	return ret;
 }
 
+int nft_rule_zero_counters(struct nft_handle *h, const char *chain,
+			   const char *table, int rulenum)
+{
+	struct iptables_command_state cs = {};
+	struct nft_rule_list *list;
+	struct nft_rule *r;
+	int ret = 0;
+
+	nft_fn = nft_rule_delete;
+
+	list = nft_rule_list_create(h);
+	if (list == NULL)
+		return 0;
+
+	r = nft_rule_find(list, chain, table, NULL, rulenum);
+	if (r == NULL) {
+		errno = ENOENT;
+		ret = 1;
+
+		goto error;
+	}
+
+	nft_rule_to_iptables_command_state(r, &cs);
+
+	cs.counters.pcnt = cs.counters.bcnt = 0;
+
+	ret =  nft_rule_append(h, chain, table, &cs,
+			nft_rule_attr_get_u64(r, NFT_RULE_ATTR_HANDLE), false);
+
+error:
+	nft_rule_list_destroy(list);
+
+	return ret;
+}
+
 static int nft_action(struct nft_handle *h, int type)
 {
 	char buf[MNL_SOCKET_BUFFER_SIZE];
diff --git a/iptables/nft.h b/iptables/nft.h
index c904e21..31e1083 100644
--- a/iptables/nft.h
+++ b/iptables/nft.h
@@ -59,6 +59,7 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table, in
 int nft_rule_list_save(struct nft_handle *h, const char *chain, const char *table, int rulenum, int counters);
 int nft_rule_save(struct nft_handle *h, const char *table, bool counters);
 int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table);
+int nft_rule_zero_counters(struct nft_handle *h, const char *chain, const char *table, int rulenum);
 
 enum nft_rule_print {
 	NFT_RULE_APPEND,
-- 
1.8.3.2


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

* [iptables-nftables - RFC v2 PATCH  17/17] xtables: Support -Z options for a given rule number
  2013-07-25 17:16 [iptables-nftables - RFC v2 PATCH 00/17] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
                   ` (15 preceding siblings ...)
  2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 16/17] nft: Add a function to reset the counters of an existing rule Tomasz Bursztyka
@ 2013-07-25 17:16 ` Tomasz Bursztyka
  16 siblings, 0 replies; 18+ messages in thread
From: Tomasz Bursztyka @ 2013-07-25 17:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Tomasz Bursztyka

Support for such command:
xtbles-multi xtables -Z foo 4

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
 iptables/xtables.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/iptables/xtables.c b/iptables/xtables.c
index 7a6509a..748dc42 100644
--- a/iptables/xtables.c
+++ b/iptables/xtables.c
@@ -1194,8 +1194,7 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table)
 		ret = nft_chain_zero_counters(h, chain, *table);
 		break;
 	case CMD_ZERO_NUM:
-		/* FIXME */
-//		ret = iptc_zero_counter(chain, rulenum, *handle);
+		ret = nft_rule_zero_counters(h, chain, *table, rulenum - 1);
 		break;
 	case CMD_LIST:
 	case CMD_LIST|CMD_ZERO:
@@ -1208,9 +1207,9 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table)
 				   cs.options&OPT_LINENUMBERS);
 		if (ret && (command & CMD_ZERO))
 			ret = nft_chain_zero_counters(h, chain, *table);
-		/* FIXME */
-/*		if (ret && (command & CMD_ZERO_NUM))
-			ret = iptc_zero_counter(chain, rulenum, *handle); */
+		if (ret && (command & CMD_ZERO_NUM))
+			ret = nft_rule_zero_counters(h, chain,
+							*table, rulenum - 1);
 		break;
 	case CMD_LIST_RULES:
 	case CMD_LIST_RULES|CMD_ZERO:
@@ -1218,9 +1217,9 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table)
 		ret = list_rules(h, chain, *table, rulenum, cs.options&OPT_VERBOSE);
 		if (ret && (command & CMD_ZERO))
 			ret = nft_chain_zero_counters(h, chain, *table);
-		/* FIXME */
-/*		if (ret && (command & CMD_ZERO_NUM))
-			ret = iptc_zero_counter(chain, rulenum, *handle); */
+		if (ret && (command & CMD_ZERO_NUM))
+			ret = nft_rule_zero_counters(h, chain,
+							*table, rulenum - 1);
 		break;
 	case CMD_NEW_CHAIN:
 		ret = nft_chain_user_add(h, chain, *table);
-- 
1.8.3.2


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

end of thread, other threads:[~2013-07-25 17:17 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-25 17:16 [iptables-nftables - RFC v2 PATCH 00/17] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 01/17] nft: Remove useless function Tomasz Bursztyka
2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 02/17] xtables: Add support for injecting xtables target into nft rule Tomasz Bursztyka
2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 03/17] xtables: add support for injecting xtables matches " Tomasz Bursztyka
2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 04/17] nft: Add nft expressions translation engine as a library Tomasz Bursztyka
2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 05/17] nft: Integrate nft translator engine in current core Tomasz Bursztyka
2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 06/17] nft: Manage xtables target parsing through translation tree Tomasz Bursztyka
2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 07/17] nft: Manage xtables matches through nft " Tomasz Bursztyka
2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 08/17] nft: Add support for xtables extensions callback to change cs Tomasz Bursztyka
2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 09/17] xtables: Add support for registering nft translation function for target Tomasz Bursztyka
2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 10/17] xtables: Add support for registering nft translation function for match Tomasz Bursztyka
2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 11/17] nft: Register all relevant xtables extensions into translation tree Tomasz Bursztyka
2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 12/17] nft: Refactor firewall printing so it reuses already parsed cs struct Tomasz Bursztyka
2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 13/17] nft: Refactor rule deletion so it compares both cs structure Tomasz Bursztyka
2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 14/17] xtables: nft: Complete refactoring on how rules are saved Tomasz Bursztyka
2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 15/17] xtables: Support pure nft expressions for DNAT extension Tomasz Bursztyka
2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 16/17] nft: Add a function to reset the counters of an existing rule Tomasz Bursztyka
2013-07-25 17:16 ` [iptables-nftables - RFC v2 PATCH 17/17] xtables: Support -Z options for a given rule number Tomasz Bursztyka

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).