From: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
To: pablo@netfilter.org
Cc: netfilter-devel@vger.kernel.org,
Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Subject: [iptables-nftables RFC v3 PATCH 03/16] nft: Add nft expressions translation engine as a library
Date: Fri, 9 Aug 2013 16:31:17 +0300 [thread overview]
Message-ID: <1376055090-26551-4-git-send-email-tomasz.bursztyka@linux.intel.com> (raw)
In-Reply-To: <1376055090-26551-1-git-send-email-tomasz.bursztyka@linux.intel.com>
libnfttrans is a generic translation engine from nft expressions to
registered "complex instructions". It works on a simple tree based
pattern matching algorithm.
Idea is to be able to register any kind of expressions suit (or pattern)
linked to a parsing function representing the "complex instruction".
Then, being able to go through the whole expression list of a rule and
retrieving the original complex instructions suit.
This will fix at once the parsing of a rule, taking into account
current compatilbe layer for extentions but also their pure nft version.
As soon as an expression will implement its method to express itself as
pur nft expression the change will be totally transparent.
Once applied on xtables (iptables over nftables), this will allow to
retrieve the exact iptables_command_state structure for instance.
However, such engine is generic enough to be reused in any other tool,
like future arptables and ebtables compatible tool over nftables.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
---
Makefile.am | 3 +
configure.ac | 1 +
include/nft-translator.h | 81 ++++++
libnfttrans/Makefile.am | 28 +++
libnfttrans/libnfttrans.pc | 11 +
libnfttrans/libnfttrans.pc.in | 11 +
libnfttrans/nft-translator.c | 571 ++++++++++++++++++++++++++++++++++++++++++
7 files changed, 706 insertions(+)
create mode 100644 include/nft-translator.h
create mode 100644 libnfttrans/Makefile.am
create mode 100644 libnfttrans/libnfttrans.pc
create mode 100644 libnfttrans/libnfttrans.pc.in
create mode 100644 libnfttrans/nft-translator.c
diff --git a/Makefile.am b/Makefile.am
index c38d360..fa762d4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,6 +4,9 @@ ACLOCAL_AMFLAGS = -I m4
AUTOMAKE_OPTIONS = foreign subdir-objects
SUBDIRS = libiptc libxtables
+if ENABLE_NFTABLES
+SUBDIRS += libnfttrans
+endif
if ENABLE_DEVEL
SUBDIRS += include
endif
diff --git a/configure.ac b/configure.ac
index 68f661c..4ca6f65 100644
--- a/configure.ac
+++ b/configure.ac
@@ -207,6 +207,7 @@ AC_CONFIG_FILES([Makefile extensions/GNUmakefile include/Makefile
libiptc/Makefile libiptc/libiptc.pc
libiptc/libip4tc.pc libiptc/libip6tc.pc
libxtables/Makefile utils/Makefile
+ libnfttrans/Makefile libnfttrans/libnfttrans.pc
include/xtables-version.h include/iptables/internal.h])
AC_OUTPUT
diff --git a/include/nft-translator.h b/include/nft-translator.h
new file mode 100644
index 0000000..318f248
--- /dev/null
+++ b/include/nft-translator.h
@@ -0,0 +1,81 @@
+/*
+ * (C) 2013 by Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef _NFT_TRANSLATOR_H
+#define _NFT_TRANSLATOR_H
+
+#include <stdint.h>
+#include <libnftables/rule.h>
+#include <libnftables/expr.h>
+
+enum nft_instruction {
+ NFT_INSTRUCTION_BITWISE = 0,
+ NFT_INSTRUCTION_BYTEORDER = 1,
+ NFT_INSTRUCTION_CMP = 2,
+ NFT_INSTRUCTION_COUNTER = 3,
+ NFT_INSTRUCTION_CT = 4,
+ NFT_INSTRUCTION_EXTHDR = 5,
+ NFT_INSTRUCTION_IMMEDIATE = 6,
+ NFT_INSTRUCTION_LIMIT = 7,
+ NFT_INSTRUCTION_LOG = 8,
+ NFT_INSTRUCTION_LOOKUP = 9,
+ NFT_INSTRUCTION_MATCH = 10,
+ NFT_INSTRUCTION_META = 11,
+ NFT_INSTRUCTION_NAT = 12,
+ NFT_INSTRUCTION_PAYLOAD = 13,
+ NFT_INSTRUCTION_REJECT = 14,
+ NFT_INSTRUCTION_TARGET = 15,
+ NFT_INSTRUCTION_MAX = 16,
+};
+
+struct nft_trans_instruction_tree;
+struct nft_trans_rule_context;
+struct nft_trans_instruction_context;
+
+typedef int (*nft_trans_parse_callback_f)(const char *ident,
+ void *data,
+ void *user_data);
+
+typedef int
+(*nft_trans_parse_instruction_f)(struct nft_trans_rule_context *rule_ctx,
+ struct nft_trans_instruction_context *first,
+ struct nft_trans_instruction_context *last,
+ nft_trans_parse_callback_f user_cb,
+ void *user_data);
+
+struct nft_trans_instruction {
+ enum nft_instruction *instructions;
+ nft_trans_parse_instruction_f function;
+};
+
+struct nft_trans_instruction_tree *nft_trans_instruction_tree_new(void);
+
+void
+nft_trans_instruction_tree_destroy(struct nft_trans_instruction_tree *tree);
+
+int nft_trans_add_instruction(struct nft_trans_instruction_tree *tree,
+ struct nft_trans_instruction *ipt_i);
+
+int
+nft_trans_rule_translate_to_instructions(struct nft_trans_instruction_tree *tree,
+ struct nft_rule *rule,
+ nft_trans_parse_callback_f user_cb,
+ void *user_data);
+
+struct nft_trans_instruction_context *
+nft_trans_instruction_context_get_next(struct nft_trans_instruction_context *i_ctx);
+
+struct nft_rule_expr *
+nft_trans_instruction_context_get_expr(struct nft_trans_instruction_context *i_ctx);
+
+struct nft_rule_expr *
+nft_trans_instruction_context_get_register(struct nft_trans_instruction_context *i_ctx,
+ int reg);
+
+#endif /* _NFT_TRANSLATOR_H */
diff --git a/libnfttrans/Makefile.am b/libnfttrans/Makefile.am
new file mode 100644
index 0000000..5befb63
--- /dev/null
+++ b/libnfttrans/Makefile.am
@@ -0,0 +1,28 @@
+# -*- Makefile -*-
+if ENABLE_NFTABLES
+if HAVE_LIBMNL
+if HAVE_LIBNFTABLES
+
+AM_CFLAGS = ${regular_CFLAGS}
+AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_builddir}/include \
+ -I${top_srcdir}/include -I./ ${kinclude_CPPFLAGS}
+
+lib_LTLIBRARIES = libnfttrans.la
+libnfttrans_la_SOURCES = nft-translator.c
+libnfttrans_la_LDFLAGS =
+libnfttrans_la_LIBADD =
+if ENABLE_STATIC
+# With --enable-static, shipped extensions are linked into the main executable,
+# so we need all the LIBADDs here too
+libnfttrans_la_LIBADD += -lm
+endif
+if ENABLE_SHARED
+libnfttrans_la_CFLAGS = ${AM_CFLAGS}
+libnfttrans_la_LIBADD += -ldl
+else
+libnfttrans_la_CFLAGS = ${AM_CFLAGS} -DNO_SHARED_LIBS=1
+endif
+
+endif # HAVE_LIBNFTABLES
+endif # HAVE_LIBMNL
+endif # ENABLE_NFTABLES
diff --git a/libnfttrans/libnfttrans.pc b/libnfttrans/libnfttrans.pc
new file mode 100644
index 0000000..fe0b4c0
--- /dev/null
+++ b/libnfttrans/libnfttrans.pc
@@ -0,0 +1,11 @@
+
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: libnfttrans
+Description: Small engine to translate nft expressions list into more complex registered subset
+Version: 1.4.19.1
+Libs: -L${libdir} -lnfttrans
+Cflags: -I${includedir}
diff --git a/libnfttrans/libnfttrans.pc.in b/libnfttrans/libnfttrans.pc.in
new file mode 100644
index 0000000..f3363de
--- /dev/null
+++ b/libnfttrans/libnfttrans.pc.in
@@ -0,0 +1,11 @@
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libnfttrans
+Description: Small engine to translate nft expressions list into more complex registered subset
+Version: @PACKAGE_VERSION@
+Libs: -L${libdir} -lnfttrans
+Cflags: -I${includedir}
diff --git a/libnfttrans/nft-translator.c b/libnfttrans/nft-translator.c
new file mode 100644
index 0000000..12bd7e5
--- /dev/null
+++ b/libnfttrans/nft-translator.c
@@ -0,0 +1,571 @@
+/*
+ * (C) 2013 by Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <linux/netfilter/nf_tables.h>
+
+#include <nft-translator.h>
+
+static const char *nft_instruction_name[NFT_INSTRUCTION_MAX] = {
+ "bitwise",
+ "byteorder",
+ "cmp",
+ "counter",
+ "ct",
+ "exthdr",
+ "immediate",
+ "limit",
+ "log",
+ "lookup",
+ "match",
+ "meta",
+ "nat",
+ "payload",
+ "reject",
+ "target",
+};
+
+typedef void (*free_function_f)(void *);
+
+struct s_list {
+ void *data;
+ struct s_list *next;
+};
+
+struct nft_trans_instruction_node {
+ struct s_list *functions;
+ struct nft_trans_instruction_node *nodes[NFT_INSTRUCTION_MAX];
+};
+
+struct nft_trans_instruction_tree {
+ struct s_list *nodes;
+ struct nft_trans_instruction_node *root;
+};
+
+struct nft_trans_register_context {
+ struct nft_rule_expr *reg[NFT_REG_MAX];
+};
+
+struct nft_trans_instruction_context {
+ struct nft_trans_instruction_context *next;
+
+ struct nft_rule_expr *current_expr;
+ enum nft_instruction instruction;
+ struct nft_trans_register_context *registers;
+};
+
+struct nft_trans_rule_context {
+ struct nft_trans_instruction_context *instr_contexts;
+};
+
+struct nft_trans_found_instruction {
+ const struct s_list *functions;
+ struct nft_trans_instruction_context *position;
+};
+
+static enum nft_instruction str2nft_intruction(const char *name)
+{
+ enum nft_instruction i;
+
+ for (i = 0; i < NFT_INSTRUCTION_MAX; i++) {
+ if (strncmp(nft_instruction_name[i], name,
+ strlen(nft_instruction_name[i])) == 0)
+ return i;
+ }
+
+ return NFT_INSTRUCTION_MAX;
+}
+
+static struct s_list *s_list_prepend(struct s_list *list, void *data)
+{
+ struct s_list *n_list;
+
+ n_list = calloc(1, sizeof(struct s_list));
+ if (n_list == NULL)
+ return list;
+
+ n_list->data = data;
+ n_list->next = list;
+
+ return n_list;
+}
+
+static void s_list_free(struct s_list *list, int data_too,
+ free_function_f _free)
+{
+ struct s_list *previous = NULL;
+
+ for (; list != NULL; list = list->next) {
+ if (previous != NULL) {
+ if (previous->data != NULL && data_too != 0) {
+ if (_free != NULL)
+ _free(previous->data);
+ else
+ free(previous->data);
+ }
+
+ free(previous);
+ }
+
+ previous = list;
+ }
+
+ if (previous != NULL) {
+ if (previous->data != NULL && data_too != 0) {
+ if (_free != NULL)
+ _free(previous->data);
+ else
+ free(previous->data);
+ }
+
+ free(previous);
+ }
+}
+
+struct nft_trans_instruction_tree *nft_trans_instruction_tree_new(void)
+{
+ struct nft_trans_instruction_tree *tree;
+
+ tree = calloc(1, sizeof(struct nft_trans_instruction_tree));
+ if (tree != NULL) {
+ tree->root = calloc(1, sizeof(struct nft_trans_instruction_node));
+ if (tree->root == NULL)
+ goto error;
+
+ tree->nodes = s_list_prepend(tree->nodes, tree->root);
+ if (tree->nodes == NULL)
+ goto error;
+ }
+
+ return tree;
+
+error:
+ free(tree);
+ return NULL;
+}
+
+static void _free_nft_trans_instruction_node(void *data)
+{
+ struct nft_trans_instruction_node *node = data;
+
+ if (node == NULL)
+ return;
+
+ s_list_free(node->functions, 0, NULL);
+ free(node);
+}
+
+void
+nft_trans_instruction_tree_destroy(struct nft_trans_instruction_tree *tree)
+{
+ if (tree == NULL)
+ return;
+
+ s_list_free(tree->nodes, 1, _free_nft_trans_instruction_node);
+ free(tree);
+}
+
+int nft_trans_add_instruction(struct nft_trans_instruction_tree *tree,
+ struct nft_trans_instruction *ipt_i)
+{
+ struct nft_trans_instruction_node *node;
+ enum nft_instruction *instr;
+
+ if (tree == NULL)
+ return -EINVAL;
+
+ node = tree->root;
+ for (instr = ipt_i->instructions;
+ *instr < NFT_INSTRUCTION_MAX; instr++) {
+ if (node->nodes[*instr] == NULL) {
+ node->nodes[*instr] = calloc(1,
+ sizeof(struct nft_trans_instruction_node));
+ if (node->nodes[*instr] == NULL)
+ return -ENOMEM;
+ }
+
+ node = node->nodes[*instr];
+ tree->nodes = s_list_prepend(tree->nodes, node);
+ }
+
+ node->functions = s_list_prepend(node->functions, ipt_i->function);
+
+ return 0;
+}
+
+static void
+free_nft_trans_instruction_context(struct nft_trans_instruction_context *i_ctx)
+{
+ if (i_ctx == NULL)
+ return;
+
+ free(i_ctx->registers);
+ free(i_ctx);
+}
+
+static void
+destroy_nft_trans_rule_context(struct nft_trans_rule_context *rule_ctx)
+{
+ if (rule_ctx == NULL)
+ return;
+
+ if (rule_ctx->instr_contexts != NULL) {
+ struct nft_trans_instruction_context *i_ctx, *prev = NULL;
+
+ for (i_ctx = rule_ctx->instr_contexts;
+ i_ctx != NULL; i_ctx = i_ctx->next) {
+ free_nft_trans_instruction_context(prev);
+ prev = i_ctx;
+ }
+
+ free_nft_trans_instruction_context(prev);
+ }
+
+ free(rule_ctx);
+}
+
+static void
+update_register_from_bitwise(struct nft_rule_expr *expr,
+ struct nft_trans_register_context *registers)
+{
+ if (nft_rule_expr_is_set(expr, NFT_EXPR_BITWISE_DREG))
+ registers->reg[nft_rule_expr_get_u32(expr,
+ NFT_EXPR_BITWISE_DREG)] = expr;
+}
+
+static void
+update_register_from_byteorder(struct nft_rule_expr *expr,
+ struct nft_trans_register_context *registers)
+{
+ if (nft_rule_expr_is_set(expr, NFT_EXPR_BYTEORDER_DREG))
+ registers->reg[nft_rule_expr_get_u32(expr,
+ NFT_EXPR_BYTEORDER_DREG)] = expr;
+}
+
+static void
+update_register_from_ct(struct nft_rule_expr *expr,
+ struct nft_trans_register_context *registers)
+{
+ if (nft_rule_expr_is_set(expr, NFT_EXPR_CT_DREG))
+ registers->reg[nft_rule_expr_get_u32(expr,
+ NFT_EXPR_CT_DREG)] = expr;
+}
+
+static void
+update_register_from_exthdr(struct nft_rule_expr *expr,
+ struct nft_trans_register_context *registers)
+{
+ if (nft_rule_expr_is_set(expr, NFT_EXPR_EXTHDR_DREG))
+ registers->reg[nft_rule_expr_get_u32(expr,
+ NFT_EXPR_EXTHDR_DREG)] = expr;
+}
+
+static void
+update_register_from_immediate(struct nft_rule_expr *expr,
+ struct nft_trans_register_context *registers)
+{
+ if (nft_rule_expr_is_set(expr, NFT_EXPR_IMM_DREG))
+ registers->reg[nft_rule_expr_get_u32(expr,
+ NFT_EXPR_IMM_DREG)] = expr;
+}
+
+static void
+update_register_from_lookup(struct nft_rule_expr *expr,
+ struct nft_trans_register_context *registers)
+{
+ if (nft_rule_expr_is_set(expr, NFT_EXPR_LOOKUP_DREG))
+ registers->reg[nft_rule_expr_get_u32(expr,
+ NFT_EXPR_LOOKUP_DREG)] = expr;
+}
+
+static void
+update_register_from_meta(struct nft_rule_expr *expr,
+ struct nft_trans_register_context *registers)
+{
+ if (nft_rule_expr_is_set(expr, NFT_EXPR_META_DREG))
+ registers->reg[nft_rule_expr_get_u32(expr,
+ NFT_EXPR_META_DREG)] = expr;
+}
+
+static void
+update_register_from_payload(struct nft_rule_expr *expr,
+ struct nft_trans_register_context *registers)
+{
+ if (nft_rule_expr_is_set(expr, NFT_EXPR_PAYLOAD_DREG))
+ registers->reg[nft_rule_expr_get_u32(expr,
+ NFT_EXPR_PAYLOAD_DREG)] = expr;
+}
+
+static struct nft_trans_register_context *
+update_registers(enum nft_instruction instruction, struct nft_rule_expr *expr,
+ struct nft_trans_register_context *registers)
+{
+ struct nft_trans_register_context *new_registers;
+
+ new_registers = calloc(1, sizeof(struct nft_trans_register_context));
+ if (new_registers == NULL)
+ return NULL;
+
+ memcpy(new_registers, registers, sizeof(struct nft_trans_register_context));
+
+ switch (instruction) {
+ case NFT_INSTRUCTION_BITWISE:
+ update_register_from_bitwise(expr, new_registers);
+ break;
+ case NFT_INSTRUCTION_BYTEORDER:
+ update_register_from_byteorder(expr, new_registers);
+ break;
+ case NFT_INSTRUCTION_CMP:
+ case NFT_INSTRUCTION_COUNTER:
+ break;
+ case NFT_INSTRUCTION_CT:
+ update_register_from_ct(expr, new_registers);
+ break;
+ case NFT_INSTRUCTION_EXTHDR:
+ update_register_from_exthdr(expr, new_registers);
+ break;
+ case NFT_INSTRUCTION_IMMEDIATE:
+ update_register_from_immediate(expr, new_registers);
+ break;
+ case NFT_INSTRUCTION_LIMIT:
+ case NFT_INSTRUCTION_LOG:
+ break;
+ case NFT_INSTRUCTION_LOOKUP:
+ update_register_from_lookup(expr, new_registers);
+ break;
+ case NFT_INSTRUCTION_MATCH:
+ break;
+ case NFT_INSTRUCTION_META:
+ update_register_from_meta(expr, new_registers);
+ break;
+ case NFT_INSTRUCTION_NAT:
+ break;
+ case NFT_INSTRUCTION_PAYLOAD:
+ update_register_from_payload(expr, new_registers);
+ break;
+ case NFT_INSTRUCTION_REJECT:
+ case NFT_INSTRUCTION_TARGET:
+ break;
+ case NFT_INSTRUCTION_MAX:
+ return NULL;
+ };
+
+ return new_registers;
+}
+
+static struct nft_trans_rule_context *
+generate_nft_trans_rule_context(struct nft_rule *rule)
+{
+ struct nft_trans_instruction_context *cur_ctx = NULL;
+ struct nft_trans_register_context *cur_regs = NULL;
+ struct nft_trans_rule_context *rule_ctx;
+ struct nft_rule_expr_iter *iter;
+ struct nft_rule_expr *expr;
+
+ rule_ctx = calloc(1, sizeof(struct nft_trans_rule_context));
+ if (rule_ctx == NULL)
+ return NULL;
+
+ iter = nft_rule_expr_iter_create(rule);
+ if (iter == NULL)
+ goto error;
+
+ cur_regs = calloc(1, sizeof(struct nft_trans_register_context));
+ if (cur_regs == NULL)
+ goto error;
+
+ expr = nft_rule_expr_iter_next(iter);
+ while (expr != NULL) {
+ struct nft_trans_instruction_context *ctx;
+ enum nft_instruction instr;
+
+ ctx = calloc(1, sizeof(struct nft_trans_instruction_context));
+ if (ctx == NULL)
+ goto error;
+
+ instr = str2nft_intruction(nft_rule_expr_get_str(expr,
+ NFT_RULE_EXPR_ATTR_NAME));
+ if (instr == NFT_INSTRUCTION_MAX)
+ goto error;
+
+ ctx->current_expr = expr;
+ ctx->instruction = instr;
+ ctx->registers = cur_regs;
+
+ if (cur_ctx == NULL)
+ rule_ctx->instr_contexts = ctx;
+ else
+ cur_ctx->next = ctx;
+
+ cur_ctx = ctx;
+
+ cur_regs = update_registers(instr, expr, cur_regs);
+ if (cur_regs == NULL)
+ goto error;
+
+ expr = nft_rule_expr_iter_next(iter);
+ }
+
+ if (cur_regs != NULL)
+ free(cur_regs);
+
+ nft_rule_expr_iter_destroy(iter);
+
+ return rule_ctx;
+
+error:
+ destroy_nft_trans_rule_context(rule_ctx);
+
+ if (cur_regs != NULL)
+ free(cur_regs);
+
+ if (iter != NULL)
+ nft_rule_expr_iter_destroy(iter);
+
+ return NULL;
+}
+
+static struct s_list *
+retrieve_nft_trans_instructions(struct nft_trans_instruction_tree *tree,
+ struct nft_trans_instruction_context *instructions)
+{
+ struct s_list *nft_trans_instructions = NULL;
+ struct nft_trans_instruction_context *ctx;
+ struct nft_trans_found_instruction *ipt_i;
+ struct nft_trans_instruction_node *node;
+
+ ctx = instructions;
+ node = tree->root;
+
+ while (ctx != NULL) {
+ if (node->nodes[ctx->instruction] != NULL) {
+ node = node->nodes[ctx->instruction];
+
+ if (node->functions != NULL) {
+ ipt_i = calloc(1,
+ sizeof(struct nft_trans_found_instruction));
+
+ ipt_i->functions = node->functions;
+ ipt_i->position = ctx;
+
+ /* It prepends since "longest path first"
+ * is applied */
+ nft_trans_instructions = s_list_prepend(
+ nft_trans_instructions, ipt_i);
+ }
+ } else
+ break;
+
+ ctx = ctx->next;
+ };
+
+ return nft_trans_instructions;
+}
+
+static struct nft_trans_instruction_context *
+execute_relevant_instruction(struct s_list *instructions,
+ struct nft_trans_rule_context *rule_ctx,
+ struct nft_trans_instruction_context *position,
+ nft_trans_parse_callback_f user_cb,
+ void *user_data)
+{
+ for (; instructions != NULL; instructions = instructions->next) {
+ struct nft_trans_found_instruction *i_f = instructions->data;
+ const struct s_list *fl;
+
+ for (fl = i_f->functions; fl != NULL; fl = fl->next) {
+ nft_trans_parse_instruction_f function = fl->data;
+
+ if (function(rule_ctx, position, i_f->position,
+ user_cb, user_data) == 0)
+ return i_f->position;
+ }
+ }
+
+ return NULL;
+}
+
+int
+nft_trans_rule_translate_to_instructions(struct nft_trans_instruction_tree *tree,
+ struct nft_rule *rule,
+ nft_trans_parse_callback_f user_cb,
+ void *user_data)
+{
+ struct nft_trans_instruction_context *position;
+ struct s_list *nft_trans_instructions;
+ struct nft_trans_rule_context *rule_ctx;
+
+ if (tree == NULL)
+ return -1;
+
+ rule_ctx = generate_nft_trans_rule_context(rule);
+ if (rule_ctx == NULL)
+ return -1;
+
+ position = rule_ctx->instr_contexts;
+ while (position != NULL) {
+ struct nft_trans_instruction_context *pos;
+
+ nft_trans_instructions = retrieve_nft_trans_instructions(tree,
+ position);
+ if (nft_trans_instructions == NULL)
+ goto error;
+
+ pos = execute_relevant_instruction(nft_trans_instructions,
+ rule_ctx, position, user_cb, user_data);
+ if (pos == NULL)
+ goto error;
+
+ s_list_free(nft_trans_instructions, 1, NULL);
+ position = pos->next;
+ }
+
+ destroy_nft_trans_rule_context(rule_ctx);
+
+ return 0;
+
+error:
+ s_list_free(nft_trans_instructions, 1, NULL);
+ destroy_nft_trans_rule_context(rule_ctx);
+
+ return -1;
+}
+
+struct nft_trans_instruction_context *
+nft_trans_instruction_context_get_next(struct nft_trans_instruction_context *i_ctx)
+{
+ if (i_ctx == NULL)
+ return NULL;
+
+ return i_ctx->next;
+}
+
+struct nft_rule_expr *
+nft_trans_instruction_context_get_expr(struct nft_trans_instruction_context *i_ctx)
+{
+ if (i_ctx == NULL)
+ return NULL;
+
+ return i_ctx->current_expr;
+}
+
+struct nft_rule_expr *
+nft_trans_instruction_context_get_register(struct nft_trans_instruction_context *i_ctx,
+ int register_index)
+{
+ if (i_ctx == NULL || i_ctx->registers == NULL ||
+ register_index >= NFT_REG_MAX)
+ return NULL;
+
+ return i_ctx->registers->reg[register_index];
+}
+
--
1.8.3.2
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2013-08-09 13:31 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-08-09 13:31 [iptables-nftables RFC v3 PATCH 00/16] Xtables extensions: full support (pure nft or compat layer) Tomasz Bursztyka
2013-08-09 13:31 ` [iptables-nftables RFC v3 PATCH 01/16] xtables: Add support for injecting xtables target into nft rule Tomasz Bursztyka
2013-08-09 13:31 ` [iptables-nftables RFC v3 PATCH 02/16] xtables: add support for injecting xtables matches " Tomasz Bursztyka
2013-08-09 13:31 ` Tomasz Bursztyka [this message]
2013-08-09 13:31 ` [iptables-nftables RFC v3 PATCH 04/16] nft: Integrate nft translator engine in current core Tomasz Bursztyka
2013-08-09 21:24 ` Pablo Neira Ayuso
2013-08-12 7:15 ` Tomasz Bursztyka
2013-08-09 13:31 ` [iptables-nftables RFC v3 PATCH 05/16] nft: Manage xtables target parsing through translation tree Tomasz Bursztyka
2013-08-09 13:31 ` [iptables-nftables RFC v3 PATCH 06/16] nft: Manage xtables matches through nft " Tomasz Bursztyka
2013-08-09 13:31 ` [iptables-nftables RFC v3 PATCH 07/16] nft: Add support for xtables extensions callback to change cs Tomasz Bursztyka
2013-08-09 13:31 ` [iptables-nftables RFC v3 PATCH 08/16] xtables: Add support for registering nft translation function for target Tomasz Bursztyka
2013-08-09 13:31 ` [iptables-nftables RFC v3 PATCH 09/16] xtables: Add support for registering nft translation function for match Tomasz Bursztyka
2013-08-09 13:31 ` [iptables-nftables RFC v3 PATCH 10/16] nft: Register all relevant xtables extensions into translation tree Tomasz Bursztyka
2013-08-09 13:31 ` [iptables-nftables RFC v3 PATCH 11/16] nft: Refactor firewall printing so it reuses already parsed cs struct Tomasz Bursztyka
2013-08-09 21:51 ` Pablo Neira Ayuso
2013-08-12 7:54 ` Tomasz Bursztyka
2013-08-12 9:30 ` Pablo Neira Ayuso
2013-08-12 10:54 ` Tomasz Bursztyka
2013-08-09 13:31 ` [iptables-nftables RFC v3 PATCH 12/16] nft: Refactor rule deletion so it compares both cs structure Tomasz Bursztyka
2013-08-09 13:31 ` [iptables-nftables RFC v3 PATCH 13/16] xtables: nft: Complete refactoring on how rules are saved Tomasz Bursztyka
2013-08-09 13:31 ` [iptables-nftables RFC v3 PATCH 14/16] xtables: Support pure nft expressions for DNAT extension Tomasz Bursztyka
2013-08-09 21:56 ` Pablo Neira Ayuso
2013-08-12 7:42 ` Tomasz Bursztyka
2013-08-09 13:31 ` [iptables-nftables RFC v3 PATCH 15/16] nft: Add a function to reset the counters of an existing rule Tomasz Bursztyka
2013-08-09 22:00 ` Pablo Neira Ayuso
2013-08-09 13:31 ` [iptables-nftables RFC v3 PATCH 16/16] xtables: Support -Z options for a given rule number Tomasz Bursztyka
2013-08-09 22:02 ` Pablo Neira Ayuso
2013-08-12 7:45 ` Tomasz Bursztyka
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1376055090-26551-4-git-send-email-tomasz.bursztyka@linux.intel.com \
--to=tomasz.bursztyka@linux.intel.com \
--cc=netfilter-devel@vger.kernel.org \
--cc=pablo@netfilter.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).