* [iptables-nftables - RFC PATCH 00/15] Xtables extensions: full support (pure nft or compat layer)
@ 2013-07-19 15:17 Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 01/15] xtables: Add support for injecting xtables target into nft rule Tomasz Bursztyka
` (14 more replies)
0 siblings, 15 replies; 16+ messages in thread
From: Tomasz Bursztyka @ 2013-07-19 15:17 UTC (permalink / raw)
To: netfilter-devel; +Cc: Tomasz Bursztyka
Hi,
So here it is: my proposal for a full support of xtables extensions, both with compat layer (match/target expressions) and also with pure nft translation.
(Note that this is only an RFC, since currently: this works only on iptables-nftables built with --enable-static, you will see why.)
Summary
-------
I came up with an idea which required a lot of refactoring, mostly to simplify the code and of course to find a solution for all our problems with xtables extensions.
In short, now process it strictelly following these path:
injecting rules: command line -> command structure -> nft rule -> kernel
reading rules : kernel -> nft rule -> command structure -> listing/saving etc...
The big difference introduced in that patch is reusing the command structure in both ways, and not only for injecting rules.
Result: clearer code, only 1 parsing of the rule expressions is necessary (_that_ is a big change), and of course we can reuse easily existing legacy code.
The nft translation process
---------------------------
Parsing the rule expressions is the key here.
Central place for it: the nft translation engine. This "engine" is a basic tree based pattern matching code.
In short: you register an "instruction" - made of a list of nft expressions - and a parsing function into a instructions tree.
For instance, one of the possible list of nft expressions for retrieving the ip addresses part of a rule is: payload, bitwise, compare.
Thus you can provide such list and a related parsing function to the "instruction tree" and when you will give a rule to be translated through the engine,
if such instructions list is found, it will call the relevant parsing function.
It of course handles the case where a pattern is made of other known smaller patterns: so is the long pattern the one which matches, or the smaller ones?
Such case is handled. The engine takes care of keeping track of all patterns. The policy of "longest pattern found" is applied for deciding which ones matches.
(It matches when the given parsing function returns a success code).
Now that we can express all parts of a rule via such "instructions", parsing function can populate the command structure.
The Xtables extensions
----------------------
Such translation engine has an interest for centralizing the parsing into one object (the command structure), but even more for future port of xtables extensions,
expressed as pure nft expressions.
Currently, nftables provides a compatibility layer to support xtables extensions as there current form: the infamouf memory blob.
But little by little, such memory blobs will be expressed as pure nft expressions list. The most obvious one was DNAT (and SNAT), thus I already implemented such support (last patch)
And there would start the troubles: about 100 of extensions, all expressed in a small subset of nft expressions... go figure which expressions list matches which extensions.
Morever that, on the contrary of current compatibility layer, the extension name is not going to be present at all.
Hopefully, the translation process described above applies perfectly here and solves that issue as well.
Patches
-------
Now the code.
Please review,
Tomasz Bursztyka (15):
xtables: Add support for injecting xtables target into nft rule
-> If a target extensions provides a way to "translate" its blob as pure nft expressions list, let's use it.
xtables: add support for injecting xtables matches into nft rule
-> same for matches extensions
nft: Add nft expressions translation engine as a library
-> Self explainatory. I made it af a library since both the core and the xtalbse extensions can use it.
nft: Integrate nft translator engine in current core
-> That patch is the step to retrieve a command structure from an nft rule, via the translation engine.
nft: Manage xtables target parsing through translation tree
-> Provides an instruction to support xt target expression list in the translation tree
nft: Manage xtables matches through nft translation tree
-> Same for xt match expression list
nft: Add support for xtables extensions callback to change cs
-> This is debatable: xtables extensions have no access to the command structure,
so instead I introduced such callback mecanism.
xtables: Add support for registering nft translation function for
target
-> Hook for registering an instruction into a translation tree, from an xtables target extension.
xtables: Add support for registering nft translation function for
match
-> Same for an xtables match extension
nft: Register all relevant xtables extensions into translation tree
-> That one is debatable, but I needed a way to register relevant extensions (ones providing translation instruction).
Note: This works _only_ if you build with --enable-static. I think it requires another solution, adding a pre_loading
function to libxtables maybe so it could work with shared/static build.
This is the main reason why I send this as an RFC.
nft: Refactor firewall printing so it reuses already parsed cs struct
-> Now we can scrap the old code which was multiple times going through the expression list, and use the command structure
nft: Refactor rule deletion so it compares both cs structure
-> Same but when deleting a rule: let's use the command structur.
nft: Remove useless function
-> Ok that one is a trivial fix, actually I should have send it appart of this patch set.
xtables: nft: Complete refactoring on how rules are saved
-> Same for listing or deleting rule: here again old code is scrapped to be able to use the command structure instead
xtables: Support pure nft expressions for DNAT extension
-> Now here is an example of an extension which can translate its blob into pure nft expressions, and can rebeilt
its blog from nfs expression via registering the right instructions/parsing function as descriped above.
Makefile.am | 3 +
configure.ac | 8 +
extensions/GNUmakefile.in | 1 +
extensions/libipt_DNAT.c | 220 +++++++++++
include/nft-translator.h | 85 ++++
include/xtables.h.in | 14 +
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 | 181 +++++++++
iptables/nft-xt-ext.h | 14 +
iptables/nft.c | 893 +++++++++++++-----------------------------
iptables/nft.h | 8 +-
iptables/xtables-events.c | 21 +-
libnfttrans/Makefile.am | 28 ++
libnfttrans/libnfttrans.pc.in | 11 +
libnfttrans/nft-translator.c | 618 +++++++++++++++++++++++++++++
19 files changed, 1637 insertions(+), 772 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/Makefile.am
create mode 100644 libnfttrans/libnfttrans.pc.in
create mode 100644 libnfttrans/nft-translator.c
--
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 [flat|nested] 16+ messages in thread
* [iptables-nftables - RFC PATCH 01/15] xtables: Add support for injecting xtables target into nft rule
2013-07-19 15:17 [iptables-nftables - RFC PATCH 00/15] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
@ 2013-07-19 15:17 ` Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 02/15] xtables: add support for injecting xtables matches " Tomasz Bursztyka
` (13 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Tomasz Bursztyka @ 2013-07-19 15:17 UTC (permalink / raw)
To: netfilter-devel; +Cc: Tomasz Bursztyka
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
configure.ac | 7 +++++++
extensions/GNUmakefile.in | 1 +
include/xtables.h.in | 5 +++++
iptables/nft.c | 20 ++++++++++++--------
4 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/configure.ac b/configure.ac
index 48a0d54..e228078 100644
--- a/configure.ac
+++ b/configure.ac
@@ -104,6 +104,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 4a8ff49..efb5502 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.in b/include/xtables.h.in
index 10b241f..767d53e 100644
--- a/include/xtables.h.in
+++ b/include/xtables.h.in
@@ -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
@@ -327,6 +329,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 72ac4b0..e773ace 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;
}
@@ -745,7 +749,7 @@ nft_rule_add(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] 16+ messages in thread
* [iptables-nftables - RFC PATCH 02/15] xtables: add support for injecting xtables matches into nft rule
2013-07-19 15:17 [iptables-nftables - RFC PATCH 00/15] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 01/15] xtables: Add support for injecting xtables target into nft rule Tomasz Bursztyka
@ 2013-07-19 15:17 ` Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 03/15] nft: Add nft expressions translation engine as a library Tomasz Bursztyka
` (12 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Tomasz Bursztyka @ 2013-07-19 15:17 UTC (permalink / raw)
To: netfilter-devel; +Cc: Tomasz Bursztyka
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
include/xtables.h.in | 3 +++
iptables/nft.c | 20 ++++++++++++--------
2 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/include/xtables.h.in b/include/xtables.h.in
index 767d53e..f2b2a23 100644
--- a/include/xtables.h.in
+++ b/include/xtables.h.in
@@ -261,6 +261,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 e773ace..90e86a1 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;
}
@@ -725,7 +729,7 @@ nft_rule_add(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) {
ret = 0;
goto err;
}
--
1.8.3.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [iptables-nftables - RFC PATCH 03/15] nft: Add nft expressions translation engine as a library
2013-07-19 15:17 [iptables-nftables - RFC PATCH 00/15] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 01/15] xtables: Add support for injecting xtables target into nft rule Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 02/15] xtables: add support for injecting xtables matches " Tomasz Bursztyka
@ 2013-07-19 15:17 ` Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 04/15] nft: Integrate nft translator engine in current core Tomasz Bursztyka
` (11 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Tomasz Bursztyka @ 2013-07-19 15:17 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.
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 | 85 ++++++
libnfttrans/Makefile.am | 28 ++
libnfttrans/libnfttrans.pc.in | 11 +
libnfttrans/nft-translator.c | 618 ++++++++++++++++++++++++++++++++++++++++++
6 files changed, 746 insertions(+)
create mode 100644 include/nft-translator.h
create mode 100644 libnfttrans/Makefile.am
create mode 100644 libnfttrans/libnfttrans.pc.in
create mode 100644 libnfttrans/nft-translator.c
diff --git a/Makefile.am b/Makefile.am
index 4eb63eb..8123a87 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 e228078..6f144bf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -176,5 +176,6 @@ 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.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..aa2eb7f
--- /dev/null
+++ b/include/nft-translator.h
@@ -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.
+ */
+
+#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_rulecontext_inhibate_instruction(struct nft_trans_rule_context *rule_ctx,
+ nft_trans_parse_instruction_f function);
+
+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/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.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..50db967
--- /dev/null
+++ b/libnfttrans/nft-translator.c
@@ -0,0 +1,618 @@
+/*
+ * (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;
+
+ /* Some complex instructions cannot be seen multiple times */
+ struct s_list *inhibited;
+};
+
+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);
+ }
+}
+
+static inline void s_list_free(struct s_list *list)
+{
+ _s_list_free(list, 0, NULL);
+}
+
+static inline void s_list_free_all(struct s_list *list)
+{
+ _s_list_free(list, 1, NULL);
+}
+
+static inline void s_list_free_full(struct s_list *list, free_function_f _free)
+{
+ _s_list_free(list, 1, _free);
+}
+
+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);
+ free(node);
+}
+
+void
+nft_trans_instruction_tree_destroy(struct nft_trans_instruction_tree *tree)
+{
+ if (tree == NULL)
+ return;
+
+ s_list_free_full(tree->nodes, _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);
+ }
+
+ if (rule_ctx->inhibited != NULL)
+ s_list_free(rule_ctx->inhibited);
+
+ 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;
+}
+
+int
+nft_trans_rulecontext_inhibate_instruction(struct nft_trans_rule_context *rule_ctx,
+ nft_trans_parse_instruction_f function)
+{
+ if (rule_ctx == NULL)
+ return -EINVAL;
+
+ rule_ctx->inhibited = s_list_prepend(rule_ctx->inhibited, function);
+
+ return 0;
+}
+
+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 bool is_instruction_inhibited(struct s_list *inhibited, void *data)
+{
+ for (; inhibited != NULL; inhibited = inhibited->next) {
+ if (inhibited->data == data)
+ return true;
+ }
+
+ return false;
+}
+
+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 (is_instruction_inhibited(rule_ctx->inhibited,
+ function))
+ continue;
+
+ 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_all(nft_trans_instructions);
+ position = pos->next;
+ }
+
+ destroy_nft_trans_rule_context(rule_ctx);
+
+ return 0;
+
+error:
+ s_list_free_all(nft_trans_instructions);
+ 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] 16+ messages in thread
* [iptables-nftables - RFC PATCH 04/15] nft: Integrate nft translator engine in current core
2013-07-19 15:17 [iptables-nftables - RFC PATCH 00/15] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
` (2 preceding siblings ...)
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 03/15] nft: Add nft expressions translation engine as a library Tomasz Bursztyka
@ 2013-07-19 15:17 ` Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 05/15] nft: Manage xtables target parsing through translation tree Tomasz Bursztyka
` (10 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Tomasz Bursztyka @ 2013-07-19 15:17 UTC (permalink / raw)
To: netfilter-devel; +Cc: Tomasz Bursztyka
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 fb26a32..2b6a037 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 5762952..030c55d 100644
--- a/iptables/nft-shared.c
+++ b/iptables/nft-shared.c
@@ -290,21 +290,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;
}
@@ -316,6 +311,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 90e86a1..155a9d3 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;
}
@@ -1697,106 +1703,142 @@ match_different(const struct xt_entry_match *a,
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)
@@ -2778,6 +2820,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] 16+ messages in thread
* [iptables-nftables - RFC PATCH 05/15] nft: Manage xtables target parsing through translation tree
2013-07-19 15:17 [iptables-nftables - RFC PATCH 00/15] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
` (3 preceding siblings ...)
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 04/15] nft: Integrate nft translator engine in current core Tomasz Bursztyka
@ 2013-07-19 15:17 ` Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 06/15] nft: Manage xtables matches through nft " Tomasz Bursztyka
` (9 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Tomasz Bursztyka @ 2013-07-19 15:17 UTC (permalink / raw)
To: netfilter-devel; +Cc: Tomasz Bursztyka
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
iptables/Makefile.am | 1 +
iptables/nft-xt-ext.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++
iptables/nft-xt-ext.h | 12 +++++++
iptables/nft.c | 3 ++
4 files changed, 104 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 2b6a037..8bc38ca 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..ad9a7f7
--- /dev/null
+++ b/iptables/nft-xt-ext.c
@@ -0,0 +1,88 @@
+/*
+ * (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 <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;
+
+ /* There cannot be more than 1 target */
+ nft_trans_rulecontext_inhibate_instruction(rule_ctx,
+ nft_parse_xt_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 155a9d3..2f00486 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);
@@ -2881,6 +2882,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] 16+ messages in thread
* [iptables-nftables - RFC PATCH 06/15] nft: Manage xtables matches through nft translation tree
2013-07-19 15:17 [iptables-nftables - RFC PATCH 00/15] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
` (4 preceding siblings ...)
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 05/15] nft: Manage xtables target parsing through translation tree Tomasz Bursztyka
@ 2013-07-19 15:17 ` Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 07/15] nft: Add support for xtables extensions callback to change cs Tomasz Bursztyka
` (8 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Tomasz Bursztyka @ 2013-07-19 15:17 UTC (permalink / raw)
To: netfilter-devel; +Cc: Tomasz Bursztyka
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 ad9a7f7..387d6fa 100644
--- a/iptables/nft-xt-ext.c
+++ b/iptables/nft-xt-ext.c
@@ -67,6 +67,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,
@@ -77,12 +126,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] 16+ messages in thread
* [iptables-nftables - RFC PATCH 07/15] nft: Add support for xtables extensions callback to change cs
2013-07-19 15:17 [iptables-nftables - RFC PATCH 00/15] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
` (5 preceding siblings ...)
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 06/15] nft: Manage xtables matches through nft " Tomasz Bursztyka
@ 2013-07-19 15:17 ` Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 08/15] xtables: Add support for registering nft translation function for target Tomasz Bursztyka
` (7 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Tomasz Bursztyka @ 2013-07-19 15:17 UTC (permalink / raw)
To: netfilter-devel; +Cc: Tomasz Bursztyka
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 387d6fa..ffc53f0 100644
--- a/iptables/nft-xt-ext.c
+++ b/iptables/nft-xt-ext.c
@@ -146,3 +146,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 2f00486..57bc3d8 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -1831,7 +1831,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] 16+ messages in thread
* [iptables-nftables - RFC PATCH 08/15] xtables: Add support for registering nft translation function for target
2013-07-19 15:17 [iptables-nftables - RFC PATCH 00/15] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
` (6 preceding siblings ...)
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 07/15] nft: Add support for xtables extensions callback to change cs Tomasz Bursztyka
@ 2013-07-19 15:17 ` Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 09/15] xtables: Add support for registering nft translation function for match Tomasz Bursztyka
` (6 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Tomasz Bursztyka @ 2013-07-19 15:17 UTC (permalink / raw)
To: netfilter-devel; +Cc: Tomasz Bursztyka
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
extensions/GNUmakefile.in | 2 +-
include/xtables.h.in | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/extensions/GNUmakefile.in b/extensions/GNUmakefile.in
index efb5502..8f8d775 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.in b/include/xtables.h.in
index f2b2a23..1658842 100644
--- a/include/xtables.h.in
+++ b/include/xtables.h.in
@@ -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
@@ -334,6 +335,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] 16+ messages in thread
* [iptables-nftables - RFC PATCH 09/15] xtables: Add support for registering nft translation function for match
2013-07-19 15:17 [iptables-nftables - RFC PATCH 00/15] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
` (7 preceding siblings ...)
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 08/15] xtables: Add support for registering nft translation function for target Tomasz Bursztyka
@ 2013-07-19 15:17 ` Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 10/15] nft: Register all relevant xtables extensions into translation tree Tomasz Bursztyka
` (5 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Tomasz Bursztyka @ 2013-07-19 15:17 UTC (permalink / raw)
To: netfilter-devel; +Cc: Tomasz Bursztyka
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
include/xtables.h.in | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/xtables.h.in b/include/xtables.h.in
index 1658842..592aae9 100644
--- a/include/xtables.h.in
+++ b/include/xtables.h.in
@@ -264,6 +264,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] 16+ messages in thread
* [iptables-nftables - RFC PATCH 10/15] nft: Register all relevant xtables extensions into translation tree
2013-07-19 15:17 [iptables-nftables - RFC PATCH 00/15] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
` (8 preceding siblings ...)
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 09/15] xtables: Add support for registering nft translation function for match Tomasz Bursztyka
@ 2013-07-19 15:17 ` Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 11/15] nft: Refactor firewall printing so it reuses already parsed cs struct Tomasz Bursztyka
` (4 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Tomasz Bursztyka @ 2013-07-19 15:17 UTC (permalink / raw)
To: netfilter-devel; +Cc: Tomasz Bursztyka
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
include/xtables.h.in | 3 +++
iptables/nft-xt-ext.c | 13 +++++++++++++
2 files changed, 16 insertions(+)
diff --git a/include/xtables.h.in b/include/xtables.h.in
index 592aae9..0f02470 100644
--- a/include/xtables.h.in
+++ b/include/xtables.h.in
@@ -403,6 +403,9 @@ 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 ffc53f0..2ce8b70 100644
--- a/iptables/nft-xt-ext.c
+++ b/iptables/nft-xt-ext.c
@@ -138,12 +138,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] 16+ messages in thread
* [iptables-nftables - RFC PATCH 11/15] nft: Refactor firewall printing so it reuses already parsed cs struct
2013-07-19 15:17 [iptables-nftables - RFC PATCH 00/15] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
` (9 preceding siblings ...)
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 10/15] nft: Register all relevant xtables extensions into translation tree Tomasz Bursztyka
@ 2013-07-19 15:17 ` Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 12/15] nft: Refactor rule deletion so it compares both cs structure Tomasz Bursztyka
` (3 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Tomasz Bursztyka @ 2013-07-19 15:17 UTC (permalink / raw)
To: netfilter-devel; +Cc: Tomasz Bursztyka
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 57bc3d8..5fd5bb9 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -2296,95 +2296,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);
@@ -2394,40 +2317,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] 16+ messages in thread
* [iptables-nftables - RFC PATCH 12/15] nft: Refactor rule deletion so it compares both cs structure
2013-07-19 15:17 [iptables-nftables - RFC PATCH 00/15] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
` (10 preceding siblings ...)
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 11/15] nft: Refactor firewall printing so it reuses already parsed cs struct Tomasz Bursztyka
@ 2013-07-19 15:17 ` Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 13/15] nft: Remove useless function Tomasz Bursztyka
` (2 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Tomasz Bursztyka @ 2013-07-19 15:17 UTC (permalink / raw)
To: netfilter-devel; +Cc: Tomasz Bursztyka
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 5fd5bb9..4476fcd 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -1843,187 +1843,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;
}
@@ -2103,18 +1980,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] 16+ messages in thread
* [iptables-nftables - RFC PATCH 13/15] nft: Remove useless function
2013-07-19 15:17 [iptables-nftables - RFC PATCH 00/15] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
` (11 preceding siblings ...)
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 12/15] nft: Refactor rule deletion so it compares both cs structure Tomasz Bursztyka
@ 2013-07-19 15:17 ` Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 14/15] xtables: nft: Complete refactoring on how rules are saved Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 15/15] xtables: Support pure nft expressions for DNAT extension Tomasz Bursztyka
14 siblings, 0 replies; 16+ messages in thread
From: Tomasz Bursztyka @ 2013-07-19 15:17 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 4476fcd..009c3b3 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -1677,33 +1677,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 int nft_parse_counters(struct nft_trans_rule_context *rule_ctx,
struct nft_trans_instruction_context *first,
struct nft_trans_instruction_context *useless,
--
1.8.3.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [iptables-nftables - RFC PATCH 14/15] xtables: nft: Complete refactoring on how rules are saved
2013-07-19 15:17 [iptables-nftables - RFC PATCH 00/15] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
` (12 preceding siblings ...)
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 13/15] nft: Remove useless function Tomasz Bursztyka
@ 2013-07-19 15:17 ` Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 15/15] xtables: Support pure nft expressions for DNAT extension Tomasz Bursztyka
14 siblings, 0 replies; 16+ messages in thread
From: Tomasz Bursztyka @ 2013-07-19 15:17 UTC (permalink / raw)
To: netfilter-devel; +Cc: Tomasz Bursztyka
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 | 284 +++++++---------------------------------------
iptables/nft.h | 8 +-
iptables/xtables-events.c | 21 ++--
7 files changed, 189 insertions(+), 404 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 030c55d..2954ff5 100644
--- a/iptables/nft-shared.c
+++ b/iptables/nft-shared.c
@@ -311,18 +311,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) {
@@ -412,6 +400,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 009c3b3..ad8b951 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;
}
@@ -804,218 +802,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;
-
- printf("-m %s", name);
-
- 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);
-
- /* 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;
-
- printf("-j %s", name);
-
- 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);
-
- /* 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) {
@@ -1027,33 +834,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");
}
@@ -1235,11 +1033,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);
@@ -1795,9 +1597,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 = {};
@@ -1943,13 +1744,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;
@@ -2318,7 +2118,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
@@ -2622,7 +2422,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 a647671..8597308 100644
--- a/iptables/nft.h
+++ b/iptables/nft.h
@@ -64,7 +64,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] 16+ messages in thread
* [iptables-nftables - RFC PATCH 15/15] xtables: Support pure nft expressions for DNAT extension
2013-07-19 15:17 [iptables-nftables - RFC PATCH 00/15] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
` (13 preceding siblings ...)
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 14/15] xtables: nft: Complete refactoring on how rules are saved Tomasz Bursztyka
@ 2013-07-19 15:17 ` Tomasz Bursztyka
14 siblings, 0 replies; 16+ messages in thread
From: Tomasz Bursztyka @ 2013-07-19 15:17 UTC (permalink / raw)
To: netfilter-devel; +Cc: Tomasz Bursztyka
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
extensions/libipt_DNAT.c | 220 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 220 insertions(+)
diff --git a/extensions/libipt_DNAT.c b/extensions/libipt_DNAT.c
index 466c9de..92b4ef2 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 <net/netfilter/nf_nat.h>
+#include <linux/netfilter/nf_tables.h>
enum {
O_TO_DEST = 0,
@@ -242,6 +243,223 @@ 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_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 & IP_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 & IP_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_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 |= IP_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 |= IP_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 +472,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] 16+ messages in thread
end of thread, other threads:[~2013-07-19 15:18 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-19 15:17 [iptables-nftables - RFC PATCH 00/15] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 01/15] xtables: Add support for injecting xtables target into nft rule Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 02/15] xtables: add support for injecting xtables matches " Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 03/15] nft: Add nft expressions translation engine as a library Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 04/15] nft: Integrate nft translator engine in current core Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 05/15] nft: Manage xtables target parsing through translation tree Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 06/15] nft: Manage xtables matches through nft " Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 07/15] nft: Add support for xtables extensions callback to change cs Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 08/15] xtables: Add support for registering nft translation function for target Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 09/15] xtables: Add support for registering nft translation function for match Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 10/15] nft: Register all relevant xtables extensions into translation tree Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 11/15] nft: Refactor firewall printing so it reuses already parsed cs struct Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 12/15] nft: Refactor rule deletion so it compares both cs structure Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 13/15] nft: Remove useless function Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 14/15] xtables: nft: Complete refactoring on how rules are saved Tomasz Bursztyka
2013-07-19 15:17 ` [iptables-nftables - RFC PATCH 15/15] xtables: Support pure nft expressions for DNAT extension 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).