From: Jan Engelhardt <jengelh@medozas.de>
To: netfilter-devel@vger.kernel.org
Subject: [PATCH 063/103] netfilter: xtables2: initial xt1->xt2 translation for tables
Date: Tue, 4 Aug 2009 09:25:47 +0200 [thread overview]
Message-ID: <1249370787-17583-64-git-send-email-jengelh@medozas.de> (raw)
In-Reply-To: <1249370787-17583-1-git-send-email-jengelh@medozas.de>
This commit adds enough logic to translate the initial table, as
provided by ip6table modules, to an xt2 table. The translation code
goes into a file xt1_compat.c that is planned to be shared with the
other *_tables too, hence the little #define/#include hack. I deem
this is the better evil -- at least when done right, and it looks
promising -- compared to the real code duplication that is currently
in place.
The "filter2" table can be used for testing: modprobing it/rmmod, and
that packets flow through xt2_do_table(). /usr/sbin/ip6tables cannot
interact with it yet as of this commit.
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
---
include/linux/netfilter/x_tables.h | 9 +
include/linux/netfilter_ipv6/ip6_tables.h | 3 +
include/net/netns/x_tables.h | 2 +-
net/ipv6/netfilter/Kconfig | 1 +
net/ipv6/netfilter/ip6_tables.c | 30 ++--
net/ipv6/netfilter/ip6table_filter2.c | 21 ++-
net/netfilter/Kconfig | 6 +
net/netfilter/Makefile | 1 +
net/netfilter/x_tables.c | 3 +-
net/netfilter/xt1_postshared.c | 51 +++++
net/netfilter/xt1_support.c | 37 ++++
net/netfilter/xt1_translat.c | 292 +++++++++++++++++++++++++++++
12 files changed, 432 insertions(+), 24 deletions(-)
create mode 100644 net/netfilter/xt1_postshared.c
create mode 100644 net/netfilter/xt1_support.c
create mode 100644 net/netfilter/xt1_translat.c
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 0608e64..cf8e65e 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -482,6 +482,8 @@ struct xt2_entry_target {
* @table: back link to table chain is contained in
* @comefrom: bitmask from which hooks the chain is entered
* (currently needed for xt_check_*)
+ * @xt1_offset: temporary field to hold the chain offset
+ * used during xt2->xt1 conversion (xt1_compat.c)
*/
struct xt2_chain {
struct list_head anchor;
@@ -489,6 +491,7 @@ struct xt2_chain {
char name[31];
struct xt2_table *table;
unsigned int comefrom;
+ unsigned int xt1_offset;
};
/**
@@ -508,6 +511,7 @@ enum {
* @chain_list: list of chains (struct xt2_chain)
* @name: name of this table
* @nfproto: nfproto the table is used exclusively with
+ * @valid_hooks: hooks the table can be entered on
* @rq_stacksize: Size of the jumpstack. This is usually set to the
* number of user chains -- since tables cannot have
* loops, at most that many jumps can possibly be made --
@@ -524,6 +528,7 @@ struct xt2_table {
struct list_head chain_list;
char name[11];
uint8_t nfproto;
+ unsigned int valid_hooks;
unsigned int rq_stacksize, stacksize;
unsigned int *stackptr;
@@ -686,11 +691,15 @@ extern struct nf_hook_ops *xt_hook_link(const struct xt_table *, nf_hookfn *);
extern void xt_hook_unlink(const struct xt_table *, struct nf_hook_ops *);
extern void *xt_repldata_create(const struct xt_table *);
+extern struct xt2_chain *xts_lookup_chain(const struct xt2_table *,
+ unsigned int);
+
extern struct xt2_rule *xt2_rule_new(struct xt2_chain *);
extern int xt2_rule_add_match(struct xt2_rule *, const char *, uint8_t,
const void *, unsigned int, bool);
extern int xt2_rule_add_target(struct xt2_rule *, const char *, uint8_t,
const void *, unsigned int, bool);
+extern void xt2_rule_free(struct xt2_rule *);
extern struct xt2_chain *xt2_chain_new(struct xt2_table *, const char *);
extern void xt2_chain_append(struct xt2_rule *);
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
index 89e0ab1..421c2d5 100644
--- a/include/linux/netfilter_ipv6/ip6_tables.h
+++ b/include/linux/netfilter_ipv6/ip6_tables.h
@@ -317,6 +317,9 @@ extern unsigned int ip6t_do_table(struct sk_buff *skb,
const struct net_device *out,
struct xt_table *table);
+extern struct xt2_table *ip6t2_register_table(struct net *,
+ const struct xt_table *, const struct ip6t_replace *);
+
/* Check for an extension */
extern int ip6t_ext_hdr(u8 nexthdr);
/* find specified header and get offset to it */
diff --git a/include/net/netns/x_tables.h b/include/net/netns/x_tables.h
index c4abab8..a63aa04 100644
--- a/include/net/netns/x_tables.h
+++ b/include/net/netns/x_tables.h
@@ -16,7 +16,7 @@ struct netns_xt {
struct netns_xt2 {
struct mutex table_lock;
struct list_head table_list[NFPROTO_NUMPROTO];
- struct xt_table *ipv6_filter;
+ struct xt2_table_link *ipv6_filter;
};
#endif
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 29d643b..46163b1 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -46,6 +46,7 @@ config IP6_NF_IPTABLES
tristate "IP6 tables support (required for filtering)"
depends on INET && IPV6
select NETFILTER_XTABLES
+ select NETFILTER_XT1_SUPPORT
default m if NETFILTER_ADVANCED=n
help
ip6tables is a general, extensible packet identification framework.
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 7eb9a57..edb00ad 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -67,6 +67,19 @@ do { \
#define inline
#endif
+static int mark_source_chains(const struct xt_table_info *,
+ unsigned int, void *);
+
+#define xtsub_entry ip6t_entry
+#define xtsub_replace ip6t_replace
+#define xtsub_error_target ip6t_error_target
+#define XTSUB_NFPROTO_IPV6 1
+#define XTSUB(x) ip6t_ ## x
+#define XTSUB2(x) ip6t2_ ## x
+
+#include "../../netfilter/xt1_translat.c"
+#include "../../netfilter/xt1_postshared.c"
+
/*
We keep a set of rules for each CPU, so we can avoid write-locking
them in the softirq when updating the counters and therefore
@@ -807,21 +820,6 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size)
return ret;
}
-static bool check_underflow(const struct ip6t_entry *e)
-{
- const struct ip6t_entry_target *t;
- unsigned int verdict;
-
- if (!unconditional(&e->ipv6))
- return false;
- t = ip6t_get_target_c(e);
- if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
- return false;
- verdict = ((struct ip6t_standard_target *)t)->verdict;
- verdict = -verdict - 1;
- return verdict == NF_DROP || verdict == NF_ACCEPT;
-}
-
static int
check_entry_size_and_hooks(struct ip6t_entry *e,
struct xt_table_info *newinfo,
@@ -853,7 +851,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
if ((unsigned char *)e - base == hook_entries[h])
newinfo->hook_entry[h] = hook_entries[h];
if ((unsigned char *)e - base == underflows[h]) {
- if (!check_underflow(e)) {
+ if (!ip6t2_check_underflow(e)) {
pr_err("Underflows must be unconditional and "
"use the STANDARD target with "
"ACCEPT/DROP\n");
diff --git a/net/ipv6/netfilter/ip6table_filter2.c b/net/ipv6/netfilter/ip6table_filter2.c
index 790552b..7456686 100644
--- a/net/ipv6/netfilter/ip6table_filter2.c
+++ b/net/ipv6/netfilter/ip6table_filter2.c
@@ -38,7 +38,14 @@ ip6table_filter_hook(unsigned int hook,
int (*okfn)(struct sk_buff *))
{
const struct net *net = dev_net((in != NULL) ? in : out);
- return ip6t_do_table(skb, hook, in, out, net->ipv6.ip6table_filter);
+ const struct xt2_table_link *link;
+ unsigned int verdict;
+
+ rcu_read_lock();
+ link = rcu_dereference(net->xt2.ipv6_filter);
+ verdict = xt2_do_table(skb, hook, in, out, link->table);
+ rcu_read_unlock();
+ return verdict;
}
/* Default to forward because I got too much mail already. */
@@ -48,6 +55,7 @@ module_param(forward, bool, 0000);
static int __net_init ip6table_filter_net_init(struct net *net)
{
struct ip6t_replace *repl = xt_repldata_create(&packet_filter);
+ struct xt2_table *table;
if (repl == NULL)
return -ENOMEM;
@@ -55,17 +63,18 @@ static int __net_init ip6table_filter_net_init(struct net *net)
((struct ip6t_standard *)repl->entries)[1].target.verdict =
-forward - 1;
- net->xt2.ipv6_filter =
- ip6t_register_table(net, &packet_filter, repl);
+ table = ip6t2_register_table(net, &packet_filter, repl);
kfree(repl);
- if (IS_ERR(net->xt2.ipv6_filter))
- return PTR_ERR(net->xt2.ipv6_filter);
+ if (IS_ERR(table))
+ return PTR_ERR(table);
+ net->xt2.ipv6_filter = xt2_tlink_lookup(net, table->name,
+ table->nfproto, XT2_NO_RCULOCK);
return 0;
}
static void __net_exit ip6table_filter_net_exit(struct net *net)
{
- ip6t_unregister_table(net->xt2.ipv6_filter);
+ xt2_table_destroy(net, net->xt2.ipv6_filter->table);
}
static struct pernet_operations ip6table_filter_net_ops = {
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 773c360..0f18528 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -301,6 +301,12 @@ config NETFILTER_XTABLES
if NETFILTER_XTABLES
+config NETFILTER_XT1_SUPPORT
+ tristate
+ select NETFILTER_XT_MATCH_QUOTA
+ ---help---
+ Protocol-agnostic part of the xt1 <-> xt2 translation layer.
+
# alphabetically ordered list of targets
config NETFILTER_XT_TARGET_CLASSIFY
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 49f62ee..fead6b4 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_NETFILTER_TPROXY) += nf_tproxy_core.o
# generic X tables
obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
+obj-$(CONFIG_NETFILTER_XT1_SUPPORT) += xt1_support.o
# targets
obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 105039a..f8ff821 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -1476,7 +1476,7 @@ int xt2_rule_add_target(struct xt2_rule *rule, const char *ext_name,
}
EXPORT_SYMBOL_GPL(xt2_rule_add_target);
-static void xt2_rule_free(struct xt2_rule *rule)
+void xt2_rule_free(struct xt2_rule *rule)
{
struct xt2_entry_target *etarget, *next_etarget;
struct xt2_entry_match *ematch, *next_ematch;
@@ -1515,6 +1515,7 @@ static void xt2_rule_free(struct xt2_rule *rule)
}
kfree(rule);
}
+EXPORT_SYMBOL_GPL(xt2_rule_free);
struct xt2_chain *xt2_chain_new(struct xt2_table *table, const char *name)
{
diff --git a/net/netfilter/xt1_postshared.c b/net/netfilter/xt1_postshared.c
new file mode 100644
index 0000000..9dcbac1
--- /dev/null
+++ b/net/netfilter/xt1_postshared.c
@@ -0,0 +1,51 @@
+/*
+ * xt1 <-> xt2 translation layer, per-nfproto specific part
+ * Copyright © Jan Engelhardt, 2009
+ *
+ * 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 <linux/kernel.h>
+#include <linux/netfilter.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+
+struct xt2_table *
+XTSUB2(register_table)(struct net *net, const struct xt_table *classic_table,
+ const struct xtsub_replace *repl)
+{
+ struct xt2_table *table;
+ void *blob;
+ int ret;
+
+ table = xt2_table_new();
+ if (table == NULL)
+ return ERR_PTR(-ENOMEM);
+ /* Need a writable copy for check_entry_and_size_hooks. */
+ ret = -ENOMEM;
+ blob = vmalloc(repl->size);
+ if (blob == NULL)
+ goto out;
+ memcpy(blob, repl->entries, repl->size);
+ strncpy(table->name, classic_table->name, sizeof(table->name));
+ table->name[sizeof(table->name)-1] = '\0';
+ table->valid_hooks = classic_table->valid_hooks;
+ table->nfproto = classic_table->af;
+
+ ret = XTSUB2(table_to_xt2)(table, blob, repl);
+ vfree(blob);
+ if (ret < 0)
+ goto out;
+ ret = xt2_table_register(net, table);
+ if (ret < 0)
+ goto out;
+ return table;
+
+ out:
+ xt2_table_destroy(NULL, table);
+ return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(XTSUB2(register_table));
diff --git a/net/netfilter/xt1_support.c b/net/netfilter/xt1_support.c
new file mode 100644
index 0000000..d15bfb7
--- /dev/null
+++ b/net/netfilter/xt1_support.c
@@ -0,0 +1,37 @@
+/*
+ * xt1 <-> xt2 translation layer, protocol independent parts
+ * Copyright © Jan Engelhardt, 2009
+ *
+ * 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 <linux/module.h>
+#include <linux/netfilter/x_tables.h>
+
+/**
+ * @table: table to search in
+ * @needle: rule offset in the xt1 blob
+ *
+ * Find the xt2 chain for a given xt1 offset. This assumes the chains are
+ * sorted by xt1_offset, which they should be given our linear translation
+ * mechanism in xt1_compat.c.
+ */
+struct xt2_chain *
+xts_lookup_chain(const struct xt2_table *table, unsigned int needle)
+{
+ struct xt2_chain *chain, *ret = NULL;
+
+ list_for_each_entry(chain, &table->chain_list, anchor) {
+ if (chain->xt1_offset <= needle)
+ ret = chain;
+ else
+ return ret;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(xts_lookup_chain);
+
+MODULE_LICENSE("GPL");
diff --git a/net/netfilter/xt1_translat.c b/net/netfilter/xt1_translat.c
new file mode 100644
index 0000000..a1663ba
--- /dev/null
+++ b/net/netfilter/xt1_translat.c
@@ -0,0 +1,292 @@
+/*
+ * xt1 <-> xt2 translation layer, proto-format specific part
+ * Copyright © Jan Engelhardt, 2009
+ *
+ * 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 <linux/kernel.h>
+#include <linux/netfilter.h>
+#include <linux/slab.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_quota.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#if !defined(XTSUB_NFPROTO_IPV6)
+# error Need to define XTSUB_NFPROTO_xxx.
+#endif
+
+#ifdef XTSUB_NFPROTO_IPV6
+static const struct ip6t_ip6 xtsub_uncond;
+
+static inline bool XTSUB2(unconditional)(const struct xtsub_entry *e)
+{
+ return memcmp(&e->ipv6, &xtsub_uncond, sizeof(xtsub_uncond)) == 0;
+}
+#endif
+
+static inline struct xt_entry_target *
+XTSUB2(get_target)(const struct xtsub_entry *e)
+{
+ return (void *)e + e->target_offset;
+}
+
+static bool XTSUB2(check_underflow)(const struct xtsub_entry *e)
+{
+ const struct xt_entry_target *t;
+ unsigned int verdict;
+
+ if (!XTSUB2(unconditional)(e))
+ return false;
+ t = XTSUB2(get_target)(e);
+ if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
+ return false;
+ verdict = ((struct xt_standard_target *)t)->verdict;
+ verdict = -verdict - 1;
+ return verdict == NF_DROP || verdict == NF_ACCEPT;
+}
+
+/**
+ * Check an xt1 entry for sanity and create chains as we find them.
+ */
+static int
+XTSUB2(rule_check)(struct xtsub_entry *e, struct xt2_table *table,
+ const void *base, const struct xtsub_replace *repl)
+{
+ const void *limit = (void *)base + repl->size;
+ unsigned int delta = (void *)e - base;
+ struct xtsub_error_target *t;
+ struct xt2_chain *chain;
+ unsigned int hook;
+
+ if ((unsigned long)e % __alignof__(struct xtsub_entry) != 0 ||
+ (void *)e + sizeof(struct xtsub_entry) >= limit ||
+ e->next_offset < sizeof(struct xtsub_entry) +
+ sizeof(struct xt_entry_target))
+ return -EINVAL;
+
+ /* Check hooks & underflows */
+ for (hook = 0; hook < ARRAY_SIZE(repl->hook_entry); ++hook) {
+ if (!(repl->valid_hooks & (1 << hook)))
+ continue;
+ if (delta == repl->hook_entry[hook]) {
+ chain = xt2_chain_new(table, NULL);
+ if (chain == NULL)
+ return -ENOMEM;
+
+ table->entrypoint[hook] = chain;
+ chain->comefrom = e->comefrom;
+ /* Aid for finding chains for a given delta. */
+ chain->xt1_offset = delta;
+ }
+ if (delta == repl->underflow[hook])
+ if (!XTSUB2(check_underflow)(e)) {
+ pr_err("Underflows must be unconditional and "
+ "use the STANDARD target with "
+ "ACCEPT/DROP\n");
+ return -EINVAL;
+ }
+ }
+
+ /* Clear counters and comefrom */
+ memset(&e->counters, 0, sizeof(e->counters));
+ e->comefrom = 0;
+
+ t = (void *)XTSUB2(get_target)(e);
+ if (strcmp(t->target.u.user.name, XT_ERROR_TARGET) == 0) {
+ t->errorname[sizeof(t->errorname)-1] = '\0';
+ if (strcmp(t->errorname, XT_ERROR_TARGET) == 0)
+ /* End of ruleset */
+ return 0;
+ chain = xt2_chain_new(table, t->errorname);
+ if (chain == NULL)
+ return -ENOMEM;
+ chain->xt1_offset = delta;
+ /* Chain marker translated. */
+ return 0;
+ }
+
+ return 1;
+}
+
+static int
+XTSUB2(target_to_xt2)(struct xt2_rule *rule, const struct xtsub_entry *entry,
+ unsigned int entry_offset)
+{
+ const struct xt_entry_target *etarget = XTSUB2(get_target)(entry);
+ const struct xt_standard_target *st;
+ struct xt2_entry_target *ntarget;
+
+ if (strcmp(etarget->u.user.name, XT_STANDARD_TARGET) != 0)
+ return xt2_rule_add_oldtarget(rule, etarget);
+
+ ntarget = kmalloc(sizeof(*ntarget), GFP_KERNEL);
+ if (ntarget == NULL)
+ return -ENOMEM;
+ INIT_LIST_HEAD(&ntarget->anchor);
+
+ st = (void *)etarget;
+ if (st->verdict == XT_RETURN) {
+ ntarget->ext = XT2_FINAL_VERDICT;
+ ntarget->verdict = XT_RETURN;
+ } else if (st->verdict < 0) {
+ ntarget->ext = XT2_FINAL_VERDICT;
+ ntarget->verdict = -st->verdict - 1;
+ } else if (st->verdict == entry_offset + entry->next_offset) {
+ ntarget->ext = XT2_FINAL_VERDICT;
+ ntarget->verdict = XT_CONTINUE;
+#ifdef XTSUB_NFPROTO_IPV6
+ } else if (entry->ipv6.flags & IP6T_F_GOTO) {
+ ntarget->ext = XT2_ACTION_GOTO;
+ ntarget->r_goto = xts_lookup_chain(rule->chain->table,
+ st->verdict);
+ /* debug: (we already checked loopfreeness before) */
+ if (ntarget->r_goto == rule->chain)
+ return -ELOOP;
+#endif
+ } else {
+ ntarget->ext = XT2_ACTION_JUMP;
+ ntarget->r_jump = xts_lookup_chain(rule->chain->table,
+ st->verdict);
+ if (ntarget->r_jump == rule->chain)
+ return -ELOOP;
+ }
+
+ list_add_tail(&ntarget->anchor, &rule->target_list);
+ return 0;
+}
+
+/**
+ * Translate a single ip6t_entry into a xt2 rule.
+ */
+static struct xt2_rule *
+XTSUB2(rule_to_xt2)(struct xt2_chain *chain, const struct xtsub_entry *entry,
+ unsigned int entry_offset)
+{
+ const struct xt_entry_match *ematch;
+ struct xt_quota_mtinfo3 byte_counter = {.flags = XT_QUOTA_GROW};
+ struct xt_quota_mtinfo3 packet_counter =
+ {.flags = XT_QUOTA_GROW | XT_QUOTA_PACKET};
+ struct xt2_rule *rule;
+ int ret;
+
+ rule = xt2_rule_new(chain);
+ if (rule == NULL)
+ return ERR_PTR(-ENOMEM);
+
+ rule->chain->comefrom = entry->comefrom;
+#ifdef XTSUB_NFPROTO_IPV6
+ rule->l4proto = entry->ipv6.proto;
+ if (entry->ipv6.flags & IP6T_INV_PROTO)
+ rule->flags |= XT2_INV_L4PROTO;
+ ret = xt2_rule_add_match(rule, "ipv6", 0, &entry->ipv6,
+ sizeof(entry->ipv6), false);
+#endif
+ if (ret < 0)
+ goto out;
+
+ xt_ematch_foreach(ematch, entry) {
+ ret = xt2_rule_add_oldmatch(rule, ematch);
+ if (ret < 0)
+ goto out;
+ }
+
+ ret = xt2_rule_add_match(rule, "quota", 3, &byte_counter,
+ sizeof(byte_counter), false);
+ if (ret < 0)
+ goto out;
+ ret = xt2_rule_add_match(rule, "quota", 3, &packet_counter,
+ sizeof(packet_counter), false);
+ if (ret < 0)
+ goto out;
+ ret = XTSUB2(target_to_xt2)(rule, entry, entry_offset);
+ if (ret < 0)
+ goto out;
+ return rule;
+
+ out:
+ xt2_rule_free(rule);
+ return ERR_PTR(ret);
+}
+
+/**
+ * @table: new table
+ * @entry0: blob of <struct ip6t_entry>s
+ * @repl: blob metadata
+ *
+ * Convert a blob table into a xt2 table.
+ */
+static int XTSUB2(table_to_xt2)(struct xt2_table *table, void *entry0,
+ const struct xtsub_replace *repl)
+{
+ struct xt_table_info mark_param;
+ struct xtsub_entry *iter;
+ unsigned int i;
+ int ret = 0;
+
+ i = 0;
+ /* Walk through entries, checking offsets, creating chains. */
+ xt_entry_foreach(iter, entry0, repl->size) {
+ ret = XTSUB2(rule_check)(iter, table, entry0, repl);
+ ++i;
+ if (ret < 0)
+ return ret;
+ else if (ret == 0)
+ continue;
+ }
+
+ if (i != repl->num_entries)
+ return -EINVAL;
+
+ /* Check hooks all assigned */
+ for (i = 0; i < ARRAY_SIZE(repl->hook_entry); ++i) {
+ /* Only hooks which are valid */
+ if (!(repl->valid_hooks & (1 << i)))
+ continue;
+ if (table->entrypoint[i] == NULL)
+ return -EINVAL;
+ }
+
+ memcpy(mark_param.hook_entry, repl->hook_entry,
+ sizeof(repl->hook_entry));
+ mark_param.size = repl->size;
+ if (!mark_source_chains(&mark_param, repl->valid_hooks, entry0))
+ return -ELOOP;
+
+ /* Now process rules. */
+ xt_entry_foreach(iter, entry0, repl->size) {
+ unsigned int hook, delta = (void *)iter - (void *)entry0;
+ const struct xt_entry_target *t;
+ struct xt2_chain *chain;
+ struct xt2_rule *rule;
+
+ t = XTSUB2(get_target)(iter);
+ if (strcmp(t->u.user.name, XT_ERROR_TARGET) == 0)
+ /* already translated */
+ continue;
+
+ /*
+ * Do not ignore base chain policies (which are rules), though.
+ * We need these for the counters.
+ */
+ chain = xts_lookup_chain(table, delta);
+ if (chain == NULL)
+ return -EINVAL;
+ rule = XTSUB2(rule_to_xt2)(chain, iter, delta);
+ if (IS_ERR(rule))
+ return PTR_ERR(rule);
+ xt2_chain_append(rule);
+
+ for (hook = 0; hook < ARRAY_SIZE(repl->underflow); ++hook) {
+ if (!(table->valid_hooks & (1 << hook)))
+ continue;
+ if (delta == repl->underflow[hook]) {
+ table->underflow[hook] = rule;
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
--
1.6.3.3
--
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:[~2009-08-04 7:27 UTC|newest]
Thread overview: 118+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-04 7:24 Xtables2 snapshot 20090804 Jan Engelhardt
2009-08-04 7:24 ` [PATCH 001/103] netfilter: xtables: remove xt_TOS v0 Jan Engelhardt
2009-08-04 7:24 ` [PATCH 002/103] netfilter: xtables: remove xt_CONNMARK v0 Jan Engelhardt
2009-08-04 7:24 ` [PATCH 003/103] netfilter: xtables: remove xt_MARK v0, v1 Jan Engelhardt
2009-08-04 7:24 ` [PATCH 004/103] netfilter: xtables: remove xt_connmark v0 Jan Engelhardt
2009-08-10 8:41 ` Patrick McHardy
2009-08-10 9:01 ` Patrick McHardy
2009-08-04 7:24 ` [PATCH 005/103] netfilter: xtables: remove xt_conntrack v0 Jan Engelhardt
2009-08-04 7:24 ` [PATCH 006/103] netfilter: xtables: remove xt_iprange v0 Jan Engelhardt
2009-08-04 7:24 ` [PATCH 007/103] netfilter: xtables: remove xt_mark v0 Jan Engelhardt
2009-08-04 7:24 ` [PATCH 008/103] netfilter: xtables: remove obsolete /proc/net/ipt_recent Jan Engelhardt
2009-08-10 8:46 ` Patrick McHardy
2009-08-04 7:24 ` [PATCH 009/103] netfilter: xtables: remove xt_owner v0 Jan Engelhardt
2009-08-04 7:24 ` [PATCH 010/103] netfilter: xtables: remove redirecting header files Jan Engelhardt
2009-08-04 7:24 ` [PATCH 011/103] netfilter: conntrack: switch hook PFs to nfproto Jan Engelhardt
2009-08-04 7:24 ` [PATCH 012/103] netfilter: xtables: " Jan Engelhardt
2009-08-04 7:24 ` [PATCH 013/103] netfilter: xtables: switch table AFs " Jan Engelhardt
2009-08-04 7:24 ` [PATCH 014/103] netfilter: xtables: remove unneeded gotos in table error paths Jan Engelhardt
2009-08-10 8:48 ` Patrick McHardy
2009-08-04 7:24 ` [PATCH 015/103] netfilter: xtables: realign struct xt_target_param Jan Engelhardt
2009-08-04 7:25 ` [PATCH 016/103] netfilter: iptables: remove unused datalen variable Jan Engelhardt
2009-08-04 7:25 ` [PATCH 017/103] netfilter: xtables: use better unconditional check Jan Engelhardt
2009-08-10 8:54 ` Patrick McHardy
2009-08-10 9:27 ` Jan Engelhardt
2009-08-10 9:31 ` Patrick McHardy
2009-08-04 7:25 ` [PATCH 018/103] netfilter: xtables: ignore unassigned hooks in check_entry_size_and_hooks Jan Engelhardt
2009-08-04 7:25 ` [PATCH 019/103] netfilter: xtables: check for unconditionality of policies Jan Engelhardt
2009-08-10 8:55 ` Patrick McHardy
2009-08-04 7:25 ` [PATCH 020/103] netfilter: xtables: check for standard verdicts in policies Jan Engelhardt
2009-08-04 7:25 ` [PATCH 021/103] netfilter: xtables: consolidate table hook functions Jan Engelhardt
2009-08-10 8:58 ` Patrick McHardy
2009-08-10 9:36 ` Jan Engelhardt
2009-08-10 9:51 ` Patrick McHardy
2009-08-04 7:25 ` [PATCH 022/103] netfilter: xtables: compact " Jan Engelhardt
2009-08-04 7:25 ` [PATCH 023/103] netfilter: xtables: generate nf_hook_ops on-demand Jan Engelhardt
2009-08-04 7:25 ` [PATCH 024/103] netfilter: xtables: mark table constant for registering functions Jan Engelhardt
2009-08-04 7:25 ` [PATCH 025/103] netfilter: xtables: constify initial table data Jan Engelhardt
2009-08-04 7:25 ` [PATCH 026/103] netfilter: xtables: use xt_table for hook instantiation Jan Engelhardt
2009-08-04 7:25 ` [PATCH 027/103] netfilter: xtables: generate initial table on-demand Jan Engelhardt
2009-08-04 7:25 ` [PATCH 028/103] netfilter: reduce NF_HOOK by one argument Jan Engelhardt
2009-08-04 7:25 ` [PATCH 029/103] netfilter: get rid of the grossness in netfilter.h Jan Engelhardt
2009-08-04 7:25 ` [PATCH 030/103] netfilter: xtables: print details on size mismatch Jan Engelhardt
2009-08-04 7:25 ` [PATCH 031/103] netfilter: xtables: constify args in compat copying functions Jan Engelhardt
2009-08-04 7:25 ` [PATCH 032/103] netfilter: xtables: add const qualifiers Jan Engelhardt
2009-08-04 7:25 ` [PATCH 033/103] netfilter: xtables: replace XT_ENTRY_ITERATE macro Jan Engelhardt
2009-08-04 7:25 ` [PATCH 034/103] netfilter: xtables: optimize call flow around xt_entry_foreach Jan Engelhardt
2009-08-04 7:25 ` [PATCH 035/103] netfilter: xtables: replace XT_MATCH_ITERATE macro Jan Engelhardt
2009-08-04 7:25 ` [PATCH 036/103] netfilter: xtables: optimize call flow around xt_ematch_foreach Jan Engelhardt
2009-08-04 7:25 ` [PATCH 037/103] netfilter: xtables: reduce arguments to translate_table Jan Engelhardt
2009-08-04 7:25 ` [PATCH 038/103] netfilter: xtables2: make ip_tables reentrant Jan Engelhardt
2009-08-04 7:25 ` [PATCH 039/103] netfilter: xtables: dissolve do_match function Jan Engelhardt
2009-08-04 7:25 ` [PATCH 040/103] netfilter: xtables: combine struct xt_match_param and xt_target_param Jan Engelhardt
2009-08-04 7:25 ` [PATCH 041/103] netfilter: xtables: substitute temporary defines by final name Jan Engelhardt
2009-08-04 7:25 ` [PATCH 042/103] netfilter: xtables: make use of xt_request_find_target Jan Engelhardt
2009-08-04 7:25 ` [PATCH 043/103] netfilter: xtables: consolidate code into xt_request_find_match Jan Engelhardt
2009-08-04 7:25 ` [PATCH 044/103] netfilter: xtables: deconstify struct xt_action_param for matches Jan Engelhardt
2009-08-04 7:25 ` [PATCH 045/103] netfilter: xtables: change hotdrop pointer to direct modification Jan Engelhardt
2009-08-04 7:25 ` [PATCH 046/103] netfilter: xtables: combine built-in extension structs Jan Engelhardt
2009-08-04 7:25 ` [PATCH 047/103] netfilter: xtables: move functions around Jan Engelhardt
2009-08-04 7:25 ` [PATCH 048/103] netfilter: ebtables: change ebt_basic_match to xt convention Jan Engelhardt
2009-08-04 7:25 ` [PATCH 049/103] netfilter: xtables: convert basic nfproto match functions into xt matches Jan Engelhardt
2009-08-04 7:25 ` [PATCH 050/103] netfilter: xtables2: initial table skeletal functions Jan Engelhardt
2009-08-04 7:25 ` [PATCH 051/103] netfilter: xtables2: initial chain " Jan Engelhardt
2009-08-04 7:25 ` [PATCH 052/103] netfilter: xtables2: initial rule " Jan Engelhardt
2009-08-04 7:25 ` [PATCH 053/103] netfilter: xtables: alternate size checking in xt_check_match Jan Engelhardt
2009-08-04 7:25 ` [PATCH 054/103] netfilter: xtables: alternate size checking in xt_check_target Jan Engelhardt
2009-08-04 7:25 ` [PATCH 055/103] netfilter: xtables2: per-rule match skeletal functions Jan Engelhardt
2009-08-04 7:25 ` [PATCH 056/103] netfilter: xtables2: per-rule target " Jan Engelhardt
2009-08-04 7:25 ` [PATCH 057/103] netfilter: xtables2: xt_check_target in combination with xt2 contexts Jan Engelhardt
2009-08-04 7:25 ` [PATCH 058/103] netfilter: xtables2: jumpstack (de)allocation functions Jan Engelhardt
2009-08-04 7:25 ` [PATCH 059/103] netfilter: xtables2: table traversal Jan Engelhardt
2009-08-04 7:25 ` [PATCH 060/103] netfilter: xt_quota: fix wrong return value (error case) Jan Engelhardt
2009-08-04 7:25 ` [PATCH 061/103] netfilter: xtables: add xt_quota revision 3 Jan Engelhardt
2009-08-04 7:25 ` [PATCH 062/103] netfilter: xtables2: make a copy of the ipv6_filter table Jan Engelhardt
2009-08-04 7:25 ` Jan Engelhardt [this message]
2009-08-04 7:25 ` [PATCH 064/103] netfilter: xtables2: xt2->xt1 translation - GET_INFO support Jan Engelhardt
2009-08-04 7:25 ` [PATCH 065/103] netfilter: xtables2: xt2->xt1 translation - GET_ENTRIES support Jan Engelhardt
2009-08-04 7:25 ` [PATCH 066/103] netfilter: xtables2: xt1->xt2 translation - SET_REPLACE support Jan Engelhardt
2009-08-04 7:25 ` [PATCH 067/103] netfilter: xtables2: return counters after SET_REPLACE Jan Engelhardt
2009-08-04 7:25 ` [PATCH 068/103] netfilter: xtables2: xt1->xt2 translation - ADD_COUNTERS support Jan Engelhardt
2009-08-04 7:25 ` [PATCH 069/103] netfilter: xtables2: xt2->xt1 translation - compat GET_INFO support Jan Engelhardt
2009-08-04 7:25 ` [PATCH 070/103] netfilter: xtables: use compat_u64 inside struct compat_xt_counters Jan Engelhardt
2009-08-04 7:25 ` [PATCH 071/103] netfilter: ip6tables: move mark_chains to xt1_perproto.c Jan Engelhardt
2009-08-04 7:25 ` [PATCH 072/103] netfilter: xtables2: xt2<->xt1 translation - compat GET_ENTRIES/SET_REPLACE support Jan Engelhardt
2009-08-04 7:25 ` [PATCH 073/103] netfilter: xtables2: compat->normal match data translation Jan Engelhardt
2009-08-04 7:25 ` [PATCH 074/103] netfilter: xtables2: compat->normal target " Jan Engelhardt
2009-08-04 7:25 ` [PATCH 075/103] netfilter: xtables2: outsource code into xts_match_to_xt1 function Jan Engelhardt
2009-08-04 7:26 ` [PATCH 076/103] netfilter: xtables2: normal->compat match data translation Jan Engelhardt
2009-08-04 7:26 ` [PATCH 077/103] netfilter: xtables2: normal->compat target " Jan Engelhardt
2009-08-04 7:26 ` [PATCH 078/103] netfilter: xtables2: packet tracing Jan Engelhardt
2009-08-04 7:26 ` [PATCH 079/103] netfilter: xtables: turn procfs entries to walk xt2 table list Jan Engelhardt
2009-08-04 7:26 ` [PATCH 080/103] netfilter: xtables2: switch ip6's tables to the xt2 table format Jan Engelhardt
2009-08-04 7:26 ` [PATCH 081/103] netfilter: ip6tables: remove obsolete packet tracing Jan Engelhardt
2009-08-04 7:26 ` [PATCH 082/103] netfilter: ip6tables: remove xt1 GET_INFO code Jan Engelhardt
2009-08-04 7:26 ` [PATCH 083/103] netfilter: ip6tables: remove xt1 GET_ENTRIES code Jan Engelhardt
2009-08-04 7:26 ` [PATCH 084/103] netfilter: ip6tables: remove unused functions (GET_ENTRIES) Jan Engelhardt
2009-08-04 7:26 ` [PATCH 085/103] netfilter: ip6tables: remove xt1 SET_REPLACE code Jan Engelhardt
2009-08-04 7:26 ` [PATCH 086/103] netfilter: ip6tables: remove unused functions (SET_REPLACE) Jan Engelhardt
2009-08-04 7:26 ` [PATCH 087/103] netfilter: ip6tables: remove xt1 ADD_COUNTERS code Jan Engelhardt
2009-08-04 7:26 ` [PATCH 088/103] netfilter: ip6tables: remove xt1/ipv6 registration functions Jan Engelhardt
2009-08-04 7:26 ` [PATCH 089/103] netfilter: ip6tables: remove remaining xt1 code Jan Engelhardt
2009-08-04 7:26 ` [PATCH 090/103] netfilter: iptables: include xt1_perproto code in ip_tables Jan Engelhardt
2009-08-04 7:26 ` [PATCH 091/103] netfilter: iptables: switch to xt2 tables Jan Engelhardt
2009-08-04 7:26 ` [PATCH 092/103] netfilter: iptables: remove unused functions Jan Engelhardt
2009-08-04 7:26 ` [PATCH 093/103] netfilter: iptables: remove xt1/ipv4 registration functions Jan Engelhardt
2009-08-04 7:26 ` [PATCH 094/103] netfilter: iptables: remove remaining xt1 code Jan Engelhardt
2009-08-04 7:26 ` [PATCH 095/103] netfilter: xt_quota: enable module lookup via arpt Jan Engelhardt
2009-08-04 7:26 ` [PATCH 096/103] netfilter: arptables: include xt1_perproto in arp_tables Jan Engelhardt
2009-08-04 7:26 ` [PATCH 097/103] netfilter: arptables: switch to xt2 tables Jan Engelhardt
2009-08-04 7:26 ` [PATCH 098/103] netfilter: arptables: remove unused functions Jan Engelhardt
2009-08-04 7:26 ` [PATCH 099/103] netfilter: arptables: remove xt1/arp registration functions Jan Engelhardt
2009-08-04 7:26 ` [PATCH 100/103] netfilter: arptables: remove remaining xt1 code Jan Engelhardt
2009-08-04 7:26 ` [PATCH 101/103] netfilter: xtables1: remove xt1 table handling Jan Engelhardt
2009-08-04 7:26 ` [PATCH 102/103] netfilter: xtables1: remove info lock Jan Engelhardt
2009-08-04 7:26 ` [PATCH 103/103] netfilter: xtables1: remove compat-userspace code Jan Engelhardt
2009-08-04 12:47 ` Xtables2 snapshot 20090804 Patrick McHardy
2009-08-04 13:26 ` Jan Engelhardt
2009-08-04 13:16 ` Jan Engelhardt
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=1249370787-17583-64-git-send-email-jengelh@medozas.de \
--to=jengelh@medozas.de \
--cc=netfilter-devel@vger.kernel.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).