* [PATCH 1/7] netfilter: nf_tables: nft_compat: release cached matches/targets
@ 2013-01-10 15:28 pablo
2013-01-10 15:28 ` [PATCH 2/7] netfilter: nf_tables: move filter chain definition to layer 3 modules pablo
` (5 more replies)
0 siblings, 6 replies; 13+ messages in thread
From: pablo @ 2013-01-10 15:28 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber, tomasz.bursztyka
From: Pablo Neira Ayuso <pablo@netfilter.org>
Release existing targets/matches that are cached in our lists.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nft_compat.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c
index 328abf1..416c89e 100644
--- a/net/netfilter/nft_compat.c
+++ b/net/netfilter/nft_compat.c
@@ -517,6 +517,14 @@ nft_match_select_ops(const struct nft_ctx *ctx,
return &nft_match->ops;
}
+static void nft_match_release(void)
+{
+ struct nft_xt *nft_match;
+
+ list_for_each_entry(nft_match, &nft_match_list, head)
+ kfree(nft_match);
+}
+
static struct nft_expr_type nft_match_type __read_mostly = {
.name = "match",
.select_ops = nft_match_select_ops,
@@ -579,6 +587,14 @@ nft_target_select_ops(const struct nft_ctx *ctx,
return &nft_target->ops;
}
+static void nft_target_release(void)
+{
+ struct nft_xt *nft_target;
+
+ list_for_each_entry(nft_target, &nft_target_list, head)
+ kfree(nft_target);
+}
+
static struct nft_expr_type nft_target_type __read_mostly = {
.name = "target",
.select_ops = nft_target_select_ops,
@@ -621,6 +637,8 @@ void nft_compat_module_exit(void)
nfnetlink_subsys_unregister(&nfnl_compat_subsys);
nft_unregister_expr(&nft_target_type);
nft_unregister_expr(&nft_match_type);
+ nft_match_release();
+ nft_target_release();
}
MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFTA_COMPAT);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 2/7] netfilter: nf_tables: move filter chain definition to layer 3 modules
2013-01-10 15:28 [PATCH 1/7] netfilter: nf_tables: nft_compat: release cached matches/targets pablo
@ 2013-01-10 15:28 ` pablo
2013-01-10 16:02 ` Patrick McHardy
2013-01-10 15:28 ` [PATCH 3/7] netfilter: nf_tables: remove hook definitions from struct nft_af_info pablo
` (4 subsequent siblings)
5 siblings, 1 reply; 13+ messages in thread
From: pablo @ 2013-01-10 15:28 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber, tomasz.bursztyka
From: Pablo Neira Ayuso <pablo@netfilter.org>
This patch moves the definition of the filter_ipv4 and filter_ipv6
default filter chains to where they belong.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/ipv4/netfilter/nf_tables_ipv4.c | 23 +++++++++++++++++++-
net/ipv6/netfilter/nf_tables_ipv6.c | 23 +++++++++++++++++++-
net/netfilter/nf_tables_api.c | 41 -----------------------------------
3 files changed, 44 insertions(+), 43 deletions(-)
diff --git a/net/ipv4/netfilter/nf_tables_ipv4.c b/net/ipv4/netfilter/nf_tables_ipv4.c
index 8827539..a0ee4c2 100644
--- a/net/ipv4/netfilter/nf_tables_ipv4.c
+++ b/net/ipv4/netfilter/nf_tables_ipv4.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
+ * Copyright (c) 2012-2013 Pablo Neira Ayuso <pablo@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -70,14 +71,34 @@ static struct pernet_operations nf_tables_ipv4_net_ops = {
.exit = nf_tables_ipv4_exit_net,
};
+static struct nf_chain_type filter_ipv4 = {
+ .family = NFPROTO_IPV4,
+ .name = "filter",
+ .type = NFT_CHAIN_T_DEFAULT,
+ .hook_mask = (1 << NF_INET_LOCAL_IN) |
+ (1 << NF_INET_LOCAL_OUT) |
+ (1 << NF_INET_FORWARD) |
+ (1 << NF_INET_PRE_ROUTING) |
+ (1 << NF_INET_POST_ROUTING),
+ .fn = {
+ [NF_INET_LOCAL_IN] = nft_do_chain,
+ [NF_INET_LOCAL_OUT] = nft_do_chain,
+ [NF_INET_FORWARD] = nft_do_chain,
+ [NF_INET_PRE_ROUTING] = nft_do_chain,
+ [NF_INET_POST_ROUTING] = nft_do_chain,
+ },
+};
+
static int __init nf_tables_ipv4_init(void)
{
+ nft_register_chain_type(&filter_ipv4);
return register_pernet_subsys(&nf_tables_ipv4_net_ops);
}
static void __exit nf_tables_ipv4_exit(void)
{
- return unregister_pernet_subsys(&nf_tables_ipv4_net_ops);
+ unregister_pernet_subsys(&nf_tables_ipv4_net_ops);
+ nft_unregister_chain_type(&filter_ipv4);
}
module_init(nf_tables_ipv4_init);
diff --git a/net/ipv6/netfilter/nf_tables_ipv6.c b/net/ipv6/netfilter/nf_tables_ipv6.c
index ff68524..e1eee09 100644
--- a/net/ipv6/netfilter/nf_tables_ipv6.c
+++ b/net/ipv6/netfilter/nf_tables_ipv6.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
+ * Copyright (c) 2012-2013 Pablo Neira Ayuso <pablo@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -67,14 +68,34 @@ static struct pernet_operations nf_tables_ipv6_net_ops = {
.exit = nf_tables_ipv6_exit_net,
};
+static struct nf_chain_type filter_ipv6 = {
+ .family = NFPROTO_IPV6,
+ .name = "filter",
+ .type = NFT_CHAIN_T_DEFAULT,
+ .hook_mask = (1 << NF_INET_LOCAL_IN) |
+ (1 << NF_INET_LOCAL_OUT) |
+ (1 << NF_INET_FORWARD) |
+ (1 << NF_INET_PRE_ROUTING) |
+ (1 << NF_INET_POST_ROUTING),
+ .fn = {
+ [NF_INET_LOCAL_IN] = nft_do_chain,
+ [NF_INET_LOCAL_OUT] = nft_do_chain,
+ [NF_INET_FORWARD] = nft_do_chain,
+ [NF_INET_PRE_ROUTING] = nft_do_chain,
+ [NF_INET_POST_ROUTING] = nft_do_chain,
+ },
+};
+
static int __init nf_tables_ipv6_init(void)
{
+ nft_register_chain_type(&filter_ipv6);
return register_pernet_subsys(&nf_tables_ipv6_net_ops);
}
static void __exit nf_tables_ipv6_exit(void)
{
- return unregister_pernet_subsys(&nf_tables_ipv6_net_ops);
+ unregister_pernet_subsys(&nf_tables_ipv6_net_ops);
+ nft_unregister_chain_type(&filter_ipv6);
}
module_init(nf_tables_ipv6_init);
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index d0dab16..a8ae0b4 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -2842,42 +2842,6 @@ int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
}
EXPORT_SYMBOL_GPL(nft_data_dump);
-static struct nf_chain_type filter_ipv4 = {
- .family = NFPROTO_IPV4,
- .name = "filter",
- .type = NFT_CHAIN_T_DEFAULT,
- .hook_mask = (1 << NF_INET_LOCAL_IN) |
- (1 << NF_INET_LOCAL_OUT) |
- (1 << NF_INET_FORWARD) |
- (1 << NF_INET_PRE_ROUTING) |
- (1 << NF_INET_POST_ROUTING),
- .fn = {
- [NF_INET_LOCAL_IN] = nft_do_chain,
- [NF_INET_LOCAL_OUT] = nft_do_chain,
- [NF_INET_FORWARD] = nft_do_chain,
- [NF_INET_PRE_ROUTING] = nft_do_chain,
- [NF_INET_POST_ROUTING] = nft_do_chain,
- },
-};
-
-static struct nf_chain_type filter_ipv6 = {
- .family = NFPROTO_IPV6,
- .name = "filter",
- .type = NFT_CHAIN_T_DEFAULT,
- .hook_mask = (1 << NF_INET_LOCAL_IN) |
- (1 << NF_INET_LOCAL_OUT) |
- (1 << NF_INET_FORWARD) |
- (1 << NF_INET_PRE_ROUTING) |
- (1 << NF_INET_POST_ROUTING),
- .fn = {
- [NF_INET_LOCAL_IN] = nft_do_chain,
- [NF_INET_LOCAL_OUT] = nft_do_chain,
- [NF_INET_FORWARD] = nft_do_chain,
- [NF_INET_PRE_ROUTING] = nft_do_chain,
- [NF_INET_POST_ROUTING] = nft_do_chain,
- },
-};
-
static int nf_tables_init_net(struct net *net)
{
INIT_LIST_HEAD(&net->nft.af_info);
@@ -2907,9 +2871,6 @@ static int __init nf_tables_module_init(void)
if (err < 0)
goto err3;
- nft_register_chain_type(&filter_ipv4);
- nft_register_chain_type(&filter_ipv6);
-
pr_info("nf_tables: (c) 2007-2009 Patrick McHardy <kaber@trash.net>\n");
return register_pernet_subsys(&nf_tables_net_ops);
err3:
@@ -2923,8 +2884,6 @@ err1:
static void __exit nf_tables_module_exit(void)
{
unregister_pernet_subsys(&nf_tables_net_ops);
- nft_unregister_chain_type(&filter_ipv4);
- nft_unregister_chain_type(&filter_ipv6);
nfnetlink_subsys_unregister(&nf_tables_subsys);
nf_tables_core_module_exit();
kfree(info);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 3/7] netfilter: nf_tables: remove hook definitions from struct nft_af_info
2013-01-10 15:28 [PATCH 1/7] netfilter: nf_tables: nft_compat: release cached matches/targets pablo
2013-01-10 15:28 ` [PATCH 2/7] netfilter: nf_tables: move filter chain definition to layer 3 modules pablo
@ 2013-01-10 15:28 ` pablo
2013-01-10 16:04 ` Patrick McHardy
2013-01-10 15:28 ` [PATCH 4/7] netfilter: nf_tables: move specific layer 3 compat code to nf_tables_ipv[4|6] pablo
` (3 subsequent siblings)
5 siblings, 1 reply; 13+ messages in thread
From: pablo @ 2013-01-10 15:28 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber, tomasz.bursztyka
From: Pablo Neira Ayuso <pablo@netfilter.org>
They are now included in the filter chain definition.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 2 --
net/ipv4/netfilter/nf_tables_ipv4.c | 5 +----
net/ipv6/netfilter/nf_tables_ipv6.c | 5 +----
net/netfilter/nf_tables_api.c | 2 --
4 files changed, 2 insertions(+), 12 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 5d9d43f..0dc7d80 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -430,7 +430,6 @@ struct nft_table {
* @nhooks: number of hooks in this family
* @owner: module owner
* @tables: used internally
- * @hooks: hookfn overrides for packet validation
*/
struct nft_af_info {
struct list_head list;
@@ -438,7 +437,6 @@ struct nft_af_info {
unsigned int nhooks;
struct module *owner;
struct list_head tables;
- nf_hookfn *hooks[NF_MAX_HOOKS];
};
extern int nft_register_afinfo(struct net *, struct nft_af_info *);
diff --git a/net/ipv4/netfilter/nf_tables_ipv4.c b/net/ipv4/netfilter/nf_tables_ipv4.c
index a0ee4c2..29e09e9 100644
--- a/net/ipv4/netfilter/nf_tables_ipv4.c
+++ b/net/ipv4/netfilter/nf_tables_ipv4.c
@@ -38,9 +38,6 @@ static struct nft_af_info nft_af_ipv4 __read_mostly = {
.family = NFPROTO_IPV4,
.nhooks = NF_INET_NUMHOOKS,
.owner = THIS_MODULE,
- .hooks = {
- [NF_INET_LOCAL_OUT] = nft_ipv4_output,
- },
};
static int nf_tables_ipv4_init_net(struct net *net)
@@ -82,7 +79,7 @@ static struct nf_chain_type filter_ipv4 = {
(1 << NF_INET_POST_ROUTING),
.fn = {
[NF_INET_LOCAL_IN] = nft_do_chain,
- [NF_INET_LOCAL_OUT] = nft_do_chain,
+ [NF_INET_LOCAL_OUT] = nft_ipv4_output,
[NF_INET_FORWARD] = nft_do_chain,
[NF_INET_PRE_ROUTING] = nft_do_chain,
[NF_INET_POST_ROUTING] = nft_do_chain,
diff --git a/net/ipv6/netfilter/nf_tables_ipv6.c b/net/ipv6/netfilter/nf_tables_ipv6.c
index e1eee09..84ccd35 100644
--- a/net/ipv6/netfilter/nf_tables_ipv6.c
+++ b/net/ipv6/netfilter/nf_tables_ipv6.c
@@ -35,9 +35,6 @@ static struct nft_af_info nft_af_ipv6 __read_mostly = {
.family = NFPROTO_IPV6,
.nhooks = NF_INET_NUMHOOKS,
.owner = THIS_MODULE,
- .hooks = {
- [NF_INET_LOCAL_OUT] = nft_ipv6_output,
- },
};
static int nf_tables_ipv6_init_net(struct net *net)
@@ -79,7 +76,7 @@ static struct nf_chain_type filter_ipv6 = {
(1 << NF_INET_POST_ROUTING),
.fn = {
[NF_INET_LOCAL_IN] = nft_do_chain,
- [NF_INET_LOCAL_OUT] = nft_do_chain,
+ [NF_INET_LOCAL_OUT] = nft_ipv6_output,
[NF_INET_FORWARD] = nft_do_chain,
[NF_INET_PRE_ROUTING] = nft_do_chain,
[NF_INET_POST_ROUTING] = nft_do_chain,
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index a8ae0b4..697b853 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -842,8 +842,6 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
ops->priority = ntohl(nla_get_be32(ha[NFTA_HOOK_PRIORITY]));
ops->priv = chain;
ops->hook = hookfn;
- if (afi->hooks[ops->hooknum])
- ops->hook = afi->hooks[ops->hooknum];
chain->flags |= NFT_BASE_CHAIN;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 4/7] netfilter: nf_tables: move specific layer 3 compat code to nf_tables_ipv[4|6]
2013-01-10 15:28 [PATCH 1/7] netfilter: nf_tables: nft_compat: release cached matches/targets pablo
2013-01-10 15:28 ` [PATCH 2/7] netfilter: nf_tables: move filter chain definition to layer 3 modules pablo
2013-01-10 15:28 ` [PATCH 3/7] netfilter: nf_tables: remove hook definitions from struct nft_af_info pablo
@ 2013-01-10 15:28 ` pablo
2013-01-10 16:09 ` Patrick McHardy
2013-01-10 15:28 ` [PATCH 5/7] netfilter: nf_tables: x_tables support as a compile time option pablo
` (2 subsequent siblings)
5 siblings, 1 reply; 13+ messages in thread
From: pablo @ 2013-01-10 15:28 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber, tomasz.bursztyka
From: Pablo Neira Ayuso <pablo@netfilter.org>
This patch moves the struct xt_action_param to struct nft_pktinfo
and that structure is filled at the beginning of the every chain.
The specific code to handle IPv4 and IPv6 now resides in
nf_tables_ipv[4|6].
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 24 +++++++---
include/net/netfilter/nf_tables_ipv4.h | 23 ++++++++++
include/net/netfilter/nf_tables_ipv6.h | 29 ++++++++++++
include/net/netns/nftables.h | 3 +-
net/ipv4/netfilter/nf_tables_ipv4.c | 30 ++++++++++---
net/ipv4/netfilter/nft_chain_nat_ipv4.c | 6 ++-
net/ipv4/netfilter/nft_chain_route_ipv4.c | 6 ++-
net/ipv6/netfilter/nf_tables_ipv6.c | 31 ++++++++++---
net/ipv6/netfilter/nft_chain_nat_ipv6.c | 6 ++-
net/ipv6/netfilter/nft_chain_route_ipv6.c | 7 ++-
net/netfilter/nf_tables_core.c | 19 +++-----
net/netfilter/nft_compat.c | 69 +++--------------------------
12 files changed, 154 insertions(+), 99 deletions(-)
create mode 100644 include/net/netfilter/nf_tables_ipv4.h
create mode 100644 include/net/netfilter/nf_tables_ipv6.h
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 0dc7d80..98e31eb 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -3,6 +3,7 @@
#include <linux/list.h>
#include <linux/netfilter.h>
+#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/nf_tables.h>
#include <net/netlink.h>
@@ -16,10 +17,22 @@ struct nft_pktinfo {
u8 nhoff;
u8 thoff;
/* for x_tables compatibility */
- bool compat_set;
- u16 fragoff;
+ struct xt_action_param xt;
};
+static inline void nft_set_pktinfo(struct nft_pktinfo *pkt,
+ const struct nf_hook_ops *ops,
+ struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out)
+{
+ pkt->skb = skb;
+ pkt->in = pkt->xt.in = in;
+ pkt->out = pkt->xt.out = out;
+ pkt->hooknum = pkt->xt.hooknum = ops->hooknum;
+ pkt->xt.family = ops->pf;
+}
+
struct nft_data {
union {
u32 data[4];
@@ -397,11 +410,8 @@ static inline struct nft_base_chain *nft_base_chain(const struct nft_chain *chai
return container_of(chain, struct nft_base_chain, chain);
}
-extern unsigned int nft_do_chain(const struct nf_hook_ops *ops,
- struct sk_buff *skb,
- const struct net_device *in,
- const struct net_device *out,
- int (*okfn)(struct sk_buff *));
+extern unsigned int nft_do_chain_pktinfo(struct nft_pktinfo *pkt,
+ const struct nf_hook_ops *ops);
/**
* struct nft_table - nf_tables table
diff --git a/include/net/netfilter/nf_tables_ipv4.h b/include/net/netfilter/nf_tables_ipv4.h
new file mode 100644
index 0000000..1be1c2c
--- /dev/null
+++ b/include/net/netfilter/nf_tables_ipv4.h
@@ -0,0 +1,23 @@
+#ifndef _NF_TABLES_IPV4_H_
+#define _NF_TABLES_IPV4_H_
+
+#include <net/netfilter/nf_tables.h>
+#include <net/ip.h>
+
+static inline void
+nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt,
+ const struct nf_hook_ops *ops,
+ struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out)
+{
+ struct iphdr *ip;
+
+ nft_set_pktinfo(pkt, ops, skb, in, out);
+
+ pkt->xt.thoff = ip_hdrlen(pkt->skb);
+ ip = ip_hdr(pkt->skb);
+ pkt->xt.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
+}
+
+#endif
diff --git a/include/net/netfilter/nf_tables_ipv6.h b/include/net/netfilter/nf_tables_ipv6.h
new file mode 100644
index 0000000..f836642
--- /dev/null
+++ b/include/net/netfilter/nf_tables_ipv6.h
@@ -0,0 +1,29 @@
+#ifndef _NF_TABLES_IPV6_H_
+#define _NF_TABLES_IPV6_H_
+
+#include <linux/netfilter_ipv6/ip6_tables.h>
+
+static inline int
+nft_set_pktinfo_ipv6(struct nft_pktinfo *pkt,
+ const struct nf_hook_ops *ops,
+ struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out)
+{
+ int protohdr, thoff = 0;
+ unsigned short frag_off;
+
+ nft_set_pktinfo(pkt, ops, skb, in, out);
+
+ protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, NULL);
+ /* If malformed, drop it */
+ if (protohdr < 0)
+ return -1;
+
+ pkt->xt.thoff = thoff;
+ pkt->xt.fragoff = frag_off;
+
+ return 0;
+}
+
+#endif
diff --git a/include/net/netns/nftables.h b/include/net/netns/nftables.h
index 255757c..a98b1c5 100644
--- a/include/net/netns/nftables.h
+++ b/include/net/netns/nftables.h
@@ -2,7 +2,8 @@
#define _NETNS_NFTABLES_H_
#include <linux/list.h>
-#include <net/netfilter/nf_tables.h>
+
+struct nft_af_info;
struct netns_nftables {
struct list_head af_info;
diff --git a/net/ipv4/netfilter/nf_tables_ipv4.c b/net/ipv4/netfilter/nf_tables_ipv4.c
index 29e09e9..9ae1dae 100644
--- a/net/ipv4/netfilter/nf_tables_ipv4.c
+++ b/net/ipv4/netfilter/nf_tables_ipv4.c
@@ -15,7 +15,7 @@
#include <linux/netfilter_ipv4.h>
#include <net/netfilter/nf_tables.h>
#include <net/net_namespace.h>
-#include <net/ip.h>
+#include <net/netfilter/nf_tables_ipv4.h>
static unsigned int nft_ipv4_output(const struct nf_hook_ops *ops,
struct sk_buff *skb,
@@ -23,6 +23,8 @@ static unsigned int nft_ipv4_output(const struct nf_hook_ops *ops,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
+ struct nft_pktinfo pkt;
+
if (unlikely(skb->len < sizeof(struct iphdr) ||
ip_hdr(skb)->ihl < sizeof(struct iphdr) / 4)) {
if (net_ratelimit())
@@ -30,8 +32,9 @@ static unsigned int nft_ipv4_output(const struct nf_hook_ops *ops,
"packet\n");
return NF_ACCEPT;
}
+ nft_set_pktinfo_ipv4(&pkt, ops, skb, in, out);
- return nft_do_chain(ops, skb, in, out, okfn);
+ return nft_do_chain_pktinfo(&pkt, ops);
}
static struct nft_af_info nft_af_ipv4 __read_mostly = {
@@ -68,6 +71,20 @@ static struct pernet_operations nf_tables_ipv4_net_ops = {
.exit = nf_tables_ipv4_exit_net,
};
+static unsigned int
+nft_do_chain_ipv4(const struct nf_hook_ops *ops,
+ struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ struct nft_pktinfo pkt;
+
+ nft_set_pktinfo_ipv4(&pkt, ops, skb, in, out);
+
+ return nft_do_chain_pktinfo(&pkt, ops);
+}
+
static struct nf_chain_type filter_ipv4 = {
.family = NFPROTO_IPV4,
.name = "filter",
@@ -78,11 +95,12 @@ static struct nf_chain_type filter_ipv4 = {
(1 << NF_INET_PRE_ROUTING) |
(1 << NF_INET_POST_ROUTING),
.fn = {
- [NF_INET_LOCAL_IN] = nft_do_chain,
+ [NF_INET_LOCAL_IN] = nft_do_chain_ipv4,
[NF_INET_LOCAL_OUT] = nft_ipv4_output,
- [NF_INET_FORWARD] = nft_do_chain,
- [NF_INET_PRE_ROUTING] = nft_do_chain,
- [NF_INET_POST_ROUTING] = nft_do_chain,
+ [NF_INET_LOCAL_OUT] = nft_do_chain_ipv4,
+ [NF_INET_FORWARD] = nft_do_chain_ipv4,
+ [NF_INET_PRE_ROUTING] = nft_do_chain_ipv4,
+ [NF_INET_POST_ROUTING] = nft_do_chain_ipv4,
},
};
diff --git a/net/ipv4/netfilter/nft_chain_nat_ipv4.c b/net/ipv4/netfilter/nft_chain_nat_ipv4.c
index ce9879e..e42d6d9 100644
--- a/net/ipv4/netfilter/nft_chain_nat_ipv4.c
+++ b/net/ipv4/netfilter/nft_chain_nat_ipv4.c
@@ -22,6 +22,7 @@
#include <net/netfilter/nf_nat.h>
#include <net/netfilter/nf_nat_core.h>
#include <net/netfilter/nf_tables.h>
+#include <net/netfilter/nf_tables_ipv4.h>
#include <net/netfilter/nf_nat_l3proto.h>
#include <net/ip.h>
@@ -39,6 +40,7 @@ static unsigned int nf_nat_fn(const struct nf_hook_ops *ops,
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
struct nf_conn_nat *nat;
enum nf_nat_manip_type maniptype = HOOK2MANIP(ops->hooknum);
+ struct nft_pktinfo pkt;
unsigned int ret;
if (ct == NULL || nf_ct_is_untracked(ct))
@@ -71,7 +73,9 @@ static unsigned int nf_nat_fn(const struct nf_hook_ops *ops,
if (nf_nat_initialized(ct, maniptype))
break;
- ret = nft_do_chain(ops, skb, in, out, okfn);
+ nft_set_pktinfo_ipv4(&pkt, ops, skb, in, out);
+
+ ret = nft_do_chain_pktinfo(&pkt, ops);
if (ret != NF_ACCEPT)
return ret;
if (!nf_nat_initialized(ct, maniptype)) {
diff --git a/net/ipv4/netfilter/nft_chain_route_ipv4.c b/net/ipv4/netfilter/nft_chain_route_ipv4.c
index 471edd3..f991eb0 100644
--- a/net/ipv4/netfilter/nft_chain_route_ipv4.c
+++ b/net/ipv4/netfilter/nft_chain_route_ipv4.c
@@ -17,6 +17,7 @@
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables.h>
+#include <net/netfilter/nf_tables_ipv4.h>
#include <net/route.h>
static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops,
@@ -26,11 +27,14 @@ static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops,
int (*okfn)(struct sk_buff *))
{
unsigned int ret;
+ struct nft_pktinfo pkt;
u32 mark;
+ nft_set_pktinfo_ipv4(&pkt, ops, skb, in, out);
+
// FIXME: length validation
mark = skb->mark;
- ret = nft_do_chain(ops, skb, in, out, okfn);
+ ret = nft_do_chain_pktinfo(&pkt, ops);
if (ret != NF_DROP && ret != NF_QUEUE) {
if (skb->mark != mark && ip_route_me_harder(skb, RTN_UNSPEC))
ret = NF_DROP;
diff --git a/net/ipv6/netfilter/nf_tables_ipv6.c b/net/ipv6/netfilter/nf_tables_ipv6.c
index 84ccd35..e2d856e 100644
--- a/net/ipv6/netfilter/nf_tables_ipv6.c
+++ b/net/ipv6/netfilter/nf_tables_ipv6.c
@@ -14,6 +14,7 @@
#include <linux/ipv6.h>
#include <linux/netfilter_ipv6.h>
#include <net/netfilter/nf_tables.h>
+#include <net/netfilter/nf_tables_ipv6.h>
static unsigned int nft_ipv6_output(const struct nf_hook_ops *ops,
struct sk_buff *skb,
@@ -21,14 +22,18 @@ static unsigned int nft_ipv6_output(const struct nf_hook_ops *ops,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
+ struct nft_pktinfo pkt;
+
if (unlikely(skb->len < sizeof(struct ipv6hdr))) {
if (net_ratelimit())
pr_info("nf_tables_ipv6: ignoring short SOCK_RAW "
"packet\n");
return NF_ACCEPT;
}
+ if (nft_set_pktinfo_ipv6(&pkt, ops, skb, in, out) < 0)
+ return NF_DROP;
- return nft_do_chain(ops, skb, in, out, okfn);
+ return nft_do_chain_pktinfo(&pkt, ops);
}
static struct nft_af_info nft_af_ipv6 __read_mostly = {
@@ -65,6 +70,22 @@ static struct pernet_operations nf_tables_ipv6_net_ops = {
.exit = nf_tables_ipv6_exit_net,
};
+static unsigned int
+nft_do_chain_ipv6(const struct nf_hook_ops *ops,
+ struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ struct nft_pktinfo pkt;
+
+ /* malformed packet, drop it */
+ if (nft_set_pktinfo_ipv6(&pkt, ops, skb, in, out) < 0)
+ return NF_DROP;
+
+ return nft_do_chain_pktinfo(&pkt, ops);
+}
+
static struct nf_chain_type filter_ipv6 = {
.family = NFPROTO_IPV6,
.name = "filter",
@@ -75,11 +96,11 @@ static struct nf_chain_type filter_ipv6 = {
(1 << NF_INET_PRE_ROUTING) |
(1 << NF_INET_POST_ROUTING),
.fn = {
- [NF_INET_LOCAL_IN] = nft_do_chain,
+ [NF_INET_LOCAL_IN] = nft_do_chain_ipv6,
[NF_INET_LOCAL_OUT] = nft_ipv6_output,
- [NF_INET_FORWARD] = nft_do_chain,
- [NF_INET_PRE_ROUTING] = nft_do_chain,
- [NF_INET_POST_ROUTING] = nft_do_chain,
+ [NF_INET_FORWARD] = nft_do_chain_ipv6,
+ [NF_INET_PRE_ROUTING] = nft_do_chain_ipv6,
+ [NF_INET_POST_ROUTING] = nft_do_chain_ipv6,
},
};
diff --git a/net/ipv6/netfilter/nft_chain_nat_ipv6.c b/net/ipv6/netfilter/nft_chain_nat_ipv6.c
index bc2f351..9f283dd 100644
--- a/net/ipv6/netfilter/nft_chain_nat_ipv6.c
+++ b/net/ipv6/netfilter/nft_chain_nat_ipv6.c
@@ -20,6 +20,7 @@
#include <net/netfilter/nf_nat.h>
#include <net/netfilter/nf_nat_core.h>
#include <net/netfilter/nf_tables.h>
+#include <net/netfilter/nf_tables_ipv6.h>
#include <net/netfilter/nf_nat_l3proto.h>
#include <net/ipv6.h>
@@ -40,6 +41,7 @@ static unsigned int nf_nat_ipv6_fn(const struct nf_hook_ops *ops,
__be16 frag_off;
int hdrlen;
u8 nexthdr;
+ struct nft_pktinfo pkt;
unsigned int ret;
if (ct == NULL || nf_ct_is_untracked(ct))
@@ -75,7 +77,9 @@ static unsigned int nf_nat_ipv6_fn(const struct nf_hook_ops *ops,
if (nf_nat_initialized(ct, maniptype))
break;
- ret = nft_do_chain(ops, skb, in, out, okfn);
+ nft_set_pktinfo_ipv6(&pkt, ops, skb, in, out);
+
+ ret = nft_do_chain_pktinfo(&pkt, ops);
if (ret != NF_ACCEPT)
return ret;
if (!nf_nat_initialized(ct, maniptype)) {
diff --git a/net/ipv6/netfilter/nft_chain_route_ipv6.c b/net/ipv6/netfilter/nft_chain_route_ipv6.c
index 0504695..341b3a8 100644
--- a/net/ipv6/netfilter/nft_chain_route_ipv6.c
+++ b/net/ipv6/netfilter/nft_chain_route_ipv6.c
@@ -19,6 +19,7 @@
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables.h>
+#include <net/netfilter/nf_tables_ipv6.h>
#include <net/route.h>
static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops,
@@ -28,10 +29,14 @@ static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops,
int (*okfn)(struct sk_buff *))
{
unsigned int ret;
+ struct nft_pktinfo pkt;
u32 mark;
+ if (nft_set_pktinfo_ipv6(&pkt, ops, skb, in, out) < 0)
+ return NF_DROP;
+
mark = skb->mark;
- ret = nft_do_chain(ops, skb, in, out, okfn);
+ ret = nft_do_chain_pktinfo(&pkt, ops);
if (ret != NF_DROP && ret != NF_QUEUE) {
if (skb->mark != mark && ip6_route_me_harder(skb))
ret = NF_DROP;
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c
index a860769..a87a5b7 100644
--- a/net/netfilter/nf_tables_core.c
+++ b/net/netfilter/nf_tables_core.c
@@ -60,22 +60,13 @@ static bool nft_payload_fast_eval(const struct nft_expr *expr,
return true;
}
-unsigned int nft_do_chain(const struct nf_hook_ops *ops,
- struct sk_buff *skb,
- const struct net_device *in,
- const struct net_device *out,
- int (*okfn)(struct sk_buff *))
+unsigned int
+nft_do_chain_pktinfo(struct nft_pktinfo *pkt, const struct nf_hook_ops *ops)
{
const struct nft_chain *chain = ops->priv;
const struct nft_rule *rule;
const struct nft_expr *expr, *last;
struct nft_data data[NFT_REG_MAX + 1];
- const struct nft_pktinfo pkt = {
- .skb = skb,
- .in = in,
- .out = out,
- .hooknum = ops->hooknum,
- };
unsigned int stackptr = 0;
struct {
const struct nft_chain *chain;
@@ -91,8 +82,8 @@ next_rule:
if (expr->ops == &nft_cmp_fast_ops)
nft_cmp_fast_eval(expr, data);
else if (expr->ops != &nft_payload_fast_ops ||
- !nft_payload_fast_eval(expr, data, &pkt))
- expr->ops->eval(expr, data, &pkt);
+ !nft_payload_fast_eval(expr, data, pkt))
+ expr->ops->eval(expr, data, pkt);
if (data[NFT_REG_VERDICT].verdict != NFT_CONTINUE)
break;
@@ -138,7 +129,7 @@ next_rule:
return nft_base_chain(chain)->policy;
}
-EXPORT_SYMBOL_GPL(nft_do_chain);
+EXPORT_SYMBOL_GPL(nft_do_chain_pktinfo);
int __init nf_tables_core_module_init(void)
{
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c
index 416c89e..1bd642c 100644
--- a/net/netfilter/nft_compat.c
+++ b/net/netfilter/nft_compat.c
@@ -17,53 +17,16 @@
#include <linux/netfilter/nf_tables.h>
#include <linux/netfilter/nf_tables_compat.h>
#include <linux/netfilter/x_tables.h>
-#include <linux/netfilter_ipv4/ip_tables.h>
-#include <linux/netfilter_ipv6/ip6_tables.h>
#include <net/netfilter/nf_tables.h>
#include <net/ip.h>
#include <net/ipv6.h>
-static inline int
-nft_compat_set_pktinfo(struct nft_pktinfo *pkt, u8 family)
-{
- int protohdr, thoff = 0;
- unsigned short frag_off;
- struct iphdr *ip;
-
- switch(family) {
- case NFPROTO_IPV4:
- pkt->thoff = ip_hdrlen(pkt->skb);
- ip = ip_hdr(pkt->skb);
- pkt->fragoff = ntohs(ip->frag_off) & IP_OFFSET;
- pkt->compat_set = true;
- break;
- case NFPROTO_IPV6:
- protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, NULL);
- /* If malformed, drop it */
- if (protohdr < 0)
- return -1;
-
- pkt->thoff = thoff;
- pkt->fragoff = frag_off;
- pkt->compat_set = true;
- break;
- }
- return 0;
-}
-
static inline void
-nft_compat_set_par(struct xt_action_param *par, const struct nft_pktinfo *pkt,
- const void *xt, const void *xt_info, u8 family)
+nft_compat_set_par(struct xt_action_param *par, void *xt, const void *xt_info)
{
par->target = xt;
par->targinfo = xt_info;
- par->in = pkt->in;
- par->out = pkt->out;
- par->hooknum = pkt->hooknum;
- par->thoff = pkt->thoff;
- par->family = family;
par->hotdrop = false;
- par->fragoff = pkt->fragoff;
}
static void nft_target_eval(const struct nft_expr *expr,
@@ -73,22 +36,13 @@ static void nft_target_eval(const struct nft_expr *expr,
void *info = nft_expr_priv(expr);
struct xt_target *target = expr->ops->data;
struct sk_buff *skb = pkt->skb;
- struct xt_action_param par;
int ret;
- if (!pkt->compat_set) {
- if (nft_compat_set_pktinfo((struct nft_pktinfo *)pkt,
- target->family) < 0) {
- data[NFT_REG_VERDICT].verdict = NF_DROP;
- return;
- }
- }
-
- nft_compat_set_par(&par, pkt, target, info, target->family);
+ nft_compat_set_par((struct xt_action_param *)&pkt->xt, target, info);
- ret = target->target(skb, &par);
+ ret = target->target(skb, &pkt->xt);
- if (par.hotdrop)
+ if (pkt->xt.hotdrop)
ret = NF_DROP;
switch(ret) {
@@ -213,22 +167,13 @@ static void nft_match_eval(const struct nft_expr *expr,
void *info = nft_expr_priv(expr);
struct xt_match *match = expr->ops->data;
struct sk_buff *skb = pkt->skb;
- struct xt_action_param par;
bool ret;
- if (!pkt->compat_set) {
- if (nft_compat_set_pktinfo((struct nft_pktinfo *)pkt,
- match->family) < 0) {
- data[NFT_REG_VERDICT].verdict = NF_DROP;
- return;
- }
- }
-
- nft_compat_set_par(&par, pkt, match, info, match->family);
+ nft_compat_set_par((struct xt_action_param *)&pkt->xt, match, info);
- ret = match->match(skb, &par);
+ ret = match->match(skb, (struct xt_action_param *)&pkt->xt);
- if (par.hotdrop) {
+ if (pkt->xt.hotdrop) {
data[NFT_REG_VERDICT].verdict = NF_DROP;
return;
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 5/7] netfilter: nf_tables: x_tables support as a compile time option
2013-01-10 15:28 [PATCH 1/7] netfilter: nf_tables: nft_compat: release cached matches/targets pablo
` (2 preceding siblings ...)
2013-01-10 15:28 ` [PATCH 4/7] netfilter: nf_tables: move specific layer 3 compat code to nf_tables_ipv[4|6] pablo
@ 2013-01-10 15:28 ` pablo
2013-01-10 15:28 ` [PATCH 6/7] netfilter: nf_tables: support 32bits-64bits x_tables compat pablo
2013-01-10 15:28 ` [PATCH 7/7] netfilter: nf_tables: fix alias for xtables over nftables module pablo
5 siblings, 0 replies; 13+ messages in thread
From: pablo @ 2013-01-10 15:28 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber, tomasz.bursztyka
From: Pablo Neira Ayuso <pablo@netfilter.org>
Restore Make x_tables over nf_tables as optional module at compile
time. The main reason for this is the dependency on x_tables symbols.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables_core.h | 3 ---
net/netfilter/Kconfig | 9 +++++++++
net/netfilter/Makefile | 3 ++-
net/netfilter/nf_tables_core.c | 6 ------
net/netfilter/nft_compat.c | 12 ++++++++++--
5 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/include/net/netfilter/nf_tables_core.h b/include/net/netfilter/nf_tables_core.h
index 12a568a..fe7b162 100644
--- a/include/net/netfilter/nf_tables_core.h
+++ b/include/net/netfilter/nf_tables_core.h
@@ -39,7 +39,4 @@ extern const struct nft_expr_ops nft_payload_fast_ops;
extern int nft_payload_module_init(void);
extern void nft_payload_module_exit(void);
-extern int nft_compat_module_init(void);
-extern void nft_compat_module_exit(void);
-
#endif /* _NET_NF_TABLES_CORE_H */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 9ba8d0e..7d1c3c0 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -474,6 +474,15 @@ config NFT_NAT
depends on NF_CONNTRACK
tristate "Netfilter nf_tables nat module"
+config NFT_COMPAT
+ depends on NF_TABLES
+ select NETFILTER_XTABLES
+ tristate "Netfilter x_tables over nf_tables module"
+ help
+ This is required if you intend to use any of existing
+ x_tables match/target extensions over the nf_tables
+ framework.
+
if NETFILTER_XTABLES
comment "Xtables combined modules"
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 1e9b653..9733bed 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -64,11 +64,12 @@ obj-$(CONFIG_NF_NAT_TFTP) += nf_nat_tftp.o
obj-$(CONFIG_NETFILTER_TPROXY) += nf_tproxy_core.o
# nf_tables
-nf_tables-objs += nf_tables_core.o nf_tables_api.o nft_compat.o
+nf_tables-objs += nf_tables_core.o nf_tables_api.o
nf_tables-objs += nft_immediate.o nft_cmp.o nft_lookup.o
nf_tables-objs += nft_bitwise.o nft_byteorder.o nft_payload.o
obj-$(CONFIG_NF_TABLES) += nf_tables.o
+obj-$(CONFIG_NFT_COMPAT) += nft_compat.o
obj-$(CONFIG_NFT_EXTHDR) += nft_exthdr.o
obj-$(CONFIG_NFT_META) += nft_meta.o
obj-$(CONFIG_NFT_CT) += nft_ct.o
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c
index a87a5b7..b9917b7 100644
--- a/net/netfilter/nf_tables_core.c
+++ b/net/netfilter/nf_tables_core.c
@@ -159,13 +159,8 @@ int __init nf_tables_core_module_init(void)
if (err < 0)
goto err6;
- err = nft_compat_module_init();
- if (err < 0)
- goto err7;
-
return 0;
-err7:
nft_payload_module_exit();
err6:
nft_byteorder_module_exit();
@@ -183,7 +178,6 @@ err1:
void nf_tables_core_module_exit(void)
{
- nft_compat_module_exit();
nft_payload_module_exit();
nft_byteorder_module_exit();
nft_bitwise_module_exit();
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c
index 1bd642c..9f84e23 100644
--- a/net/netfilter/nft_compat.c
+++ b/net/netfilter/nft_compat.c
@@ -548,7 +548,7 @@ static struct nft_expr_type nft_target_type __read_mostly = {
.owner = THIS_MODULE,
};
-int __init nft_compat_module_init(void)
+static int __init nft_compat_module_init(void)
{
int ret;
@@ -577,7 +577,7 @@ err_match:
return ret;
}
-void nft_compat_module_exit(void)
+static void __exit nft_compat_module_exit(void)
{
nfnetlink_subsys_unregister(&nfnl_compat_subsys);
nft_unregister_expr(&nft_target_type);
@@ -587,3 +587,11 @@ void nft_compat_module_exit(void)
}
MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFTA_COMPAT);
+
+module_init(nft_compat_module_init);
+module_exit(nft_compat_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
+MODULE_ALIAS_NFT_EXPR("match");
+MODULE_ALIAS_NFT_EXPR("target");
--
1.7.10.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 6/7] netfilter: nf_tables: support 32bits-64bits x_tables compat
2013-01-10 15:28 [PATCH 1/7] netfilter: nf_tables: nft_compat: release cached matches/targets pablo
` (3 preceding siblings ...)
2013-01-10 15:28 ` [PATCH 5/7] netfilter: nf_tables: x_tables support as a compile time option pablo
@ 2013-01-10 15:28 ` pablo
2013-01-10 16:12 ` Patrick McHardy
2013-01-10 15:28 ` [PATCH 7/7] netfilter: nf_tables: fix alias for xtables over nftables module pablo
5 siblings, 1 reply; 13+ messages in thread
From: pablo @ 2013-01-10 15:28 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber, tomasz.bursztyka
From: Pablo Neira Ayuso <pablo@netfilter.org>
This patch adds support for existing compat infrastructure in
matches/targets.
This adds a new callback compat_to_blob that uses memcpy
instead of copy_to_user.
The standard target has no compat_to_blob since user-space
is using the native immediate expression to issue verdicts.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/linux/netfilter/x_tables.h | 2 +
net/ipv4/netfilter/ipt_ULOG.c | 14 ++++++
net/netfilter/nft_compat.c | 83 ++++++++++++++++++++++++++++++++----
net/netfilter/xt_limit.c | 16 +++++++
4 files changed, 107 insertions(+), 8 deletions(-)
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 8d674a7..f2cc078 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -307,6 +307,7 @@ struct xt_match {
/* Called when userspace align differs from kernel space one */
void (*compat_from_user)(void *dst, const void *src);
int (*compat_to_user)(void __user *dst, const void *src);
+ void (*compat_to_blob)(void *dst, const void *src);
#endif
/* Set this to THIS_MODULE if you are a module, otherwise NULL */
struct module *me;
@@ -347,6 +348,7 @@ struct xt_target {
/* Called when userspace align differs from kernel space one */
void (*compat_from_user)(void *dst, const void *src);
int (*compat_to_user)(void __user *dst, const void *src);
+ void (*compat_to_blob)(void *dst, const void *src);
#endif
/* Set this to THIS_MODULE if you are a module, otherwise NULL */
struct module *me;
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index b5ef3cb..6941581 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -356,6 +356,19 @@ static int ulog_tg_compat_to_user(void __user *dst, const void *src)
memcpy(cl.prefix, l->prefix, sizeof(cl.prefix));
return copy_to_user(dst, &cl, sizeof(cl)) ? -EFAULT : 0;
}
+
+static void ulog_tg_compat_to_blob(void *dst, const void *src)
+{
+ const struct ipt_ulog_info *l = src;
+ struct compat_ipt_ulog_info cl = {
+ .nl_group = l->nl_group,
+ .copy_range = l->copy_range,
+ .qthreshold = l->qthreshold,
+ };
+
+ memcpy(cl.prefix, l->prefix, sizeof(cl.prefix));
+ memcpy(dst, &cl, sizeof(cl));
+}
#endif /* CONFIG_COMPAT */
static struct xt_target ulog_tg_reg __read_mostly = {
@@ -368,6 +381,7 @@ static struct xt_target ulog_tg_reg __read_mostly = {
.compatsize = sizeof(struct compat_ipt_ulog_info),
.compat_from_user = ulog_tg_compat_from_user,
.compat_to_user = ulog_tg_compat_to_user,
+ .compat_to_blob = ulog_tg_compat_to_blob,
#endif
.me = THIS_MODULE,
};
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c
index 9f84e23..3cd6fd6 100644
--- a/net/netfilter/nft_compat.c
+++ b/net/netfilter/nft_compat.c
@@ -1,5 +1,5 @@
/*
- * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
+ * (C) 2012-2013 by Pablo Neira Ayuso <pablo@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -82,6 +82,19 @@ nft_target_set_tgchk_param(struct xt_tgchk_param *par,
par->family = ctx->afi->family;
}
+static void target_compat_from_user(struct xt_target *t, void *in, void *out)
+{
+ int pad;
+
+ if (t->compat_from_user) {
+ t->compat_from_user(out, in);
+ pad = XT_ALIGN(t->targetsize) - t->targetsize;
+ if (pad > 0)
+ memset(out + t->targetsize, 0, pad);
+ } else
+ memcpy(out, in, XT_ALIGN(t->targetsize));
+}
+
static int
nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
const struct nlattr * const tb[])
@@ -92,8 +105,7 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
size_t size = XT_ALIGN(nla_len(tb[NFTA_TARGET_INFO]));
int ret;
- memcpy(info, nla_data(tb[NFTA_TARGET_INFO]),
- XT_ALIGN(target->targetsize));
+ target_compat_from_user(target, nla_data(tb[NFTA_TARGET_INFO]), info);
nft_target_set_tgchk_param(&par, ctx, target, info);
@@ -122,6 +134,26 @@ nft_target_destroy(const struct nft_expr *expr)
module_put(target->me);
}
+static int
+target_dump_info(struct sk_buff *skb, const struct xt_target *t, const void *in)
+{
+ void *out;
+ int ret;
+
+ if (t->compat_to_blob) {
+ out = kmalloc(XT_ALIGN(t->targetsize), GFP_ATOMIC);
+ if (out == NULL)
+ return -ENOMEM;
+
+ t->compat_to_blob(out, in);
+ ret = nla_put(skb, NFTA_TARGET_INFO, XT_ALIGN(t->targetsize), out);
+ kfree(out);
+ } else
+ ret = nla_put(skb, NFTA_TARGET_INFO, XT_ALIGN(t->targetsize), in);
+
+ return ret;
+}
+
static int nft_target_dump(struct sk_buff *skb, const struct nft_expr *expr)
{
const struct xt_target *target = expr->ops->data;
@@ -129,7 +161,7 @@ static int nft_target_dump(struct sk_buff *skb, const struct nft_expr *expr)
if (nla_put_string(skb, NFTA_TARGET_NAME, target->name) ||
nla_put_be32(skb, NFTA_TARGET_REV, htonl(target->revision)) ||
- nla_put(skb, NFTA_TARGET_INFO, XT_ALIGN(target->targetsize), info))
+ target_dump_info(skb, target, info))
goto nla_put_failure;
return 0;
@@ -214,6 +246,19 @@ nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx,
par->family = ctx->afi->family;
}
+static void match_compat_from_user(struct xt_match *m, void *in, void *out)
+{
+ int pad;
+
+ if (m->compat_from_user) {
+ m->compat_from_user(out, in);
+ pad = XT_ALIGN(m->matchsize) - m->matchsize;
+ if (pad > 0)
+ memset(out + m->matchsize, 0, pad);
+ } else
+ memcpy(out, in, XT_ALIGN(m->matchsize));
+}
+
static int
nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
const struct nlattr * const tb[])
@@ -224,7 +269,7 @@ nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
size_t size = XT_ALIGN(nla_len(tb[NFTA_MATCH_INFO]));
int ret;
- memcpy(info, nla_data(tb[NFTA_MATCH_INFO]), XT_ALIGN(match->matchsize));
+ match_compat_from_user(match, nla_data(tb[NFTA_MATCH_INFO]), info);
nft_match_set_mtchk_param(&par, ctx, match, info);
@@ -247,6 +292,26 @@ nft_match_destroy(const struct nft_expr *expr)
module_put(match->me);
}
+static int
+match_dump_info(struct sk_buff *skb, const struct xt_match *m, const void *in)
+{
+ void *out;
+ int ret;
+
+ if (m->compat_to_blob) {
+ out = kmalloc(XT_ALIGN(m->matchsize), GFP_ATOMIC);
+ if (out == NULL)
+ return -ENOMEM;
+
+ m->compat_to_blob(out, in);
+ ret = nla_put(skb, NFTA_MATCH_INFO, XT_ALIGN(m->matchsize), out);
+ kfree(out);
+ } else
+ ret = nla_put(skb, NFTA_MATCH_INFO, XT_ALIGN(m->matchsize), in);
+
+ return ret;
+}
+
static int nft_match_dump(struct sk_buff *skb, const struct nft_expr *expr)
{
void *info = nft_expr_priv(expr);
@@ -254,7 +319,7 @@ static int nft_match_dump(struct sk_buff *skb, const struct nft_expr *expr)
if (nla_put_string(skb, NFTA_MATCH_NAME, match->name) ||
nla_put_be32(skb, NFTA_MATCH_REV, htonl(match->revision)) ||
- nla_put(skb, NFTA_MATCH_INFO, XT_ALIGN(match->matchsize), info))
+ match_dump_info(skb, match, info))
goto nla_put_failure;
return 0;
@@ -449,7 +514,8 @@ nft_match_select_ops(const struct nft_ctx *ctx,
return ERR_PTR(-ENOMEM);
nft_match->ops.type = &nft_match_type;
- nft_match->ops.size = NFT_EXPR_SIZE(XT_ALIGN(match->matchsize));
+ nft_match->ops.size = NFT_EXPR_SIZE(XT_ALIGN(match->matchsize) +
+ xt_compat_match_offset(match));
nft_match->ops.eval = nft_match_eval;
nft_match->ops.init = nft_match_init;
nft_match->ops.destroy = nft_match_destroy;
@@ -519,7 +585,8 @@ nft_target_select_ops(const struct nft_ctx *ctx,
return ERR_PTR(-ENOMEM);
nft_target->ops.type = &nft_target_type;
- nft_target->ops.size = NFT_EXPR_SIZE(XT_ALIGN(target->targetsize));
+ nft_target->ops.size = NFT_EXPR_SIZE(XT_ALIGN(target->targetsize) +
+ xt_compat_target_offset(target));
nft_target->ops.eval = nft_target_eval;
nft_target->ops.init = nft_target_init;
nft_target->ops.destroy = nft_target_destroy;
diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c
index 5c22ce8..4a19bd4 100644
--- a/net/netfilter/xt_limit.c
+++ b/net/netfilter/xt_limit.c
@@ -177,6 +177,21 @@ static int limit_mt_compat_to_user(void __user *dst, const void *src)
};
return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
}
+
+static void limit_mt_compat_to_blob(void *dst, const void *src)
+{
+ const struct xt_rateinfo *m = src;
+ struct compat_xt_rateinfo cm = {
+ .avg = m->avg,
+ .burst = m->burst,
+ .prev = m->prev,
+ .credit = m->credit,
+ .credit_cap = m->credit_cap,
+ .cost = m->cost,
+ .master = m->prev >> 32,
+ };
+ memcpy(dst, &cm, sizeof(cm));
+}
#endif /* CONFIG_COMPAT */
static struct xt_match limit_mt_reg __read_mostly = {
@@ -191,6 +206,7 @@ static struct xt_match limit_mt_reg __read_mostly = {
.compatsize = sizeof(struct compat_xt_rateinfo),
.compat_from_user = limit_mt_compat_from_user,
.compat_to_user = limit_mt_compat_to_user,
+ .compat_to_blob = limit_mt_compat_to_blob,
#endif
.me = THIS_MODULE,
};
--
1.7.10.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 7/7] netfilter: nf_tables: fix alias for xtables over nftables module
2013-01-10 15:28 [PATCH 1/7] netfilter: nf_tables: nft_compat: release cached matches/targets pablo
` (4 preceding siblings ...)
2013-01-10 15:28 ` [PATCH 6/7] netfilter: nf_tables: support 32bits-64bits x_tables compat pablo
@ 2013-01-10 15:28 ` pablo
5 siblings, 0 replies; 13+ messages in thread
From: pablo @ 2013-01-10 15:28 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber, tomasz.bursztyka
From: Pablo Neira Ayuso <pablo@netfilter.org>
modinfo nft_compat
[...]
alias: nfnetlink-subsys-NFNL_SUBSYS_NFTA_COMPAT
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nft_compat.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c
index 3cd6fd6..e00b05e 100644
--- a/net/netfilter/nft_compat.c
+++ b/net/netfilter/nft_compat.c
@@ -653,7 +653,7 @@ static void __exit nft_compat_module_exit(void)
nft_target_release();
}
-MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFTA_COMPAT);
+MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFT_COMPAT);
module_init(nft_compat_module_init);
module_exit(nft_compat_module_exit);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 2/7] netfilter: nf_tables: move filter chain definition to layer 3 modules
2013-01-10 15:28 ` [PATCH 2/7] netfilter: nf_tables: move filter chain definition to layer 3 modules pablo
@ 2013-01-10 16:02 ` Patrick McHardy
0 siblings, 0 replies; 13+ messages in thread
From: Patrick McHardy @ 2013-01-10 16:02 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel, tomasz.bursztyka
On Thu, Jan 10, 2013 at 04:28:36PM +0100, pablo@netfilter.org wrote:
> From: Pablo Neira Ayuso <pablo@netfilter.org>
>
> This patch moves the definition of the filter_ipv4 and filter_ipv6
> default filter chains to where they belong.
>
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> ---
> net/ipv4/netfilter/nf_tables_ipv4.c | 23 +++++++++++++++++++-
> net/ipv6/netfilter/nf_tables_ipv6.c | 23 +++++++++++++++++++-
> net/netfilter/nf_tables_api.c | 41 -----------------------------------
> 3 files changed, 44 insertions(+), 43 deletions(-)
>
> diff --git a/net/ipv4/netfilter/nf_tables_ipv4.c b/net/ipv4/netfilter/nf_tables_ipv4.c
> index 8827539..a0ee4c2 100644
> --- a/net/ipv4/netfilter/nf_tables_ipv4.c
> +++ b/net/ipv4/netfilter/nf_tables_ipv4.c
> @@ -1,5 +1,6 @@
> /*
> * Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
> + * Copyright (c) 2012-2013 Pablo Neira Ayuso <pablo@netfilter.org>
> *
> * This program is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License version 2 as
> @@ -70,14 +71,34 @@ static struct pernet_operations nf_tables_ipv4_net_ops = {
> .exit = nf_tables_ipv4_exit_net,
> };
>
> +static struct nf_chain_type filter_ipv4 = {
> + .family = NFPROTO_IPV4,
> + .name = "filter",
> + .type = NFT_CHAIN_T_DEFAULT,
> + .hook_mask = (1 << NF_INET_LOCAL_IN) |
> + (1 << NF_INET_LOCAL_OUT) |
> + (1 << NF_INET_FORWARD) |
> + (1 << NF_INET_PRE_ROUTING) |
> + (1 << NF_INET_POST_ROUTING),
> + .fn = {
> + [NF_INET_LOCAL_IN] = nft_do_chain,
> + [NF_INET_LOCAL_OUT] = nft_do_chain,
> + [NF_INET_FORWARD] = nft_do_chain,
> + [NF_INET_PRE_ROUTING] = nft_do_chain,
> + [NF_INET_POST_ROUTING] = nft_do_chain,
> + },
> +};
I'm still thinking about how to rework this, the chain types currently
break the LOCAL_OUT check for short SOCK_RAW packets and setting of
the transport layer header pointer before invoking nft_do_chain().
I'll also need some additional overloading for multi family tables,
so I think we need to rethink this scheme.
Feel free to apply your patch, but I'll probably will rework this very
soon anyway.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/7] netfilter: nf_tables: remove hook definitions from struct nft_af_info
2013-01-10 15:28 ` [PATCH 3/7] netfilter: nf_tables: remove hook definitions from struct nft_af_info pablo
@ 2013-01-10 16:04 ` Patrick McHardy
2013-01-10 16:19 ` Pablo Neira Ayuso
0 siblings, 1 reply; 13+ messages in thread
From: Patrick McHardy @ 2013-01-10 16:04 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel, tomasz.bursztyka
On Thu, Jan 10, 2013 at 04:28:37PM +0100, pablo@netfilter.org wrote:
> From: Pablo Neira Ayuso <pablo@netfilter.org>
>
> They are now included in the filter chain definition.
>
Ok should have looked at the entire series before responding.
I do still need the table hooks for the multi family tables,
so I'd suggest to keep the current state until I've come up
with a scheme that accomodates all our needs.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 4/7] netfilter: nf_tables: move specific layer 3 compat code to nf_tables_ipv[4|6]
2013-01-10 15:28 ` [PATCH 4/7] netfilter: nf_tables: move specific layer 3 compat code to nf_tables_ipv[4|6] pablo
@ 2013-01-10 16:09 ` Patrick McHardy
2013-01-10 16:20 ` Pablo Neira Ayuso
0 siblings, 1 reply; 13+ messages in thread
From: Patrick McHardy @ 2013-01-10 16:09 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel, tomasz.bursztyka
On Thu, Jan 10, 2013 at 04:28:38PM +0100, pablo@netfilter.org wrote:
> From: Pablo Neira Ayuso <pablo@netfilter.org>
>
> This patch moves the struct xt_action_param to struct nft_pktinfo
> and that structure is filled at the beginning of the every chain.
>
> The specific code to handle IPv4 and IPv6 now resides in
> nf_tables_ipv[4|6].
>
> +extern unsigned int nft_do_chain_pktinfo(struct nft_pktinfo *pkt,
> + const struct nf_hook_ops *ops);
Passing the pktinfo is something I also need to fix the transport layer
parsing. I don't like that function name at all though, just keep
nft_do_chain()?
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 6/7] netfilter: nf_tables: support 32bits-64bits x_tables compat
2013-01-10 15:28 ` [PATCH 6/7] netfilter: nf_tables: support 32bits-64bits x_tables compat pablo
@ 2013-01-10 16:12 ` Patrick McHardy
0 siblings, 0 replies; 13+ messages in thread
From: Patrick McHardy @ 2013-01-10 16:12 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel, tomasz.bursztyka
On Thu, Jan 10, 2013 at 04:28:40PM +0100, pablo@netfilter.org wrote:
> From: Pablo Neira Ayuso <pablo@netfilter.org>
>
> This patch adds support for existing compat infrastructure in
> matches/targets.
>
> This adds a new callback compat_to_blob that uses memcpy
> instead of copy_to_user.
>
Alternatively we could use the existing compat callbacks and set_fs()
to avoid duplicating all of them.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/7] netfilter: nf_tables: remove hook definitions from struct nft_af_info
2013-01-10 16:04 ` Patrick McHardy
@ 2013-01-10 16:19 ` Pablo Neira Ayuso
0 siblings, 0 replies; 13+ messages in thread
From: Pablo Neira Ayuso @ 2013-01-10 16:19 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, tomasz.bursztyka
On Thu, Jan 10, 2013 at 05:04:18PM +0100, Patrick McHardy wrote:
> On Thu, Jan 10, 2013 at 04:28:37PM +0100, pablo@netfilter.org wrote:
> > From: Pablo Neira Ayuso <pablo@netfilter.org>
> >
> > They are now included in the filter chain definition.
> >
>
> Ok should have looked at the entire series before responding.
> I do still need the table hooks for the multi family tables,
> so I'd suggest to keep the current state until I've come up
> with a scheme that accomodates all our needs.
OK, I'll rework this patch to fix the output path of filter. I will
keep the table hooks so you can still use it.
Thanks Patrick.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 4/7] netfilter: nf_tables: move specific layer 3 compat code to nf_tables_ipv[4|6]
2013-01-10 16:09 ` Patrick McHardy
@ 2013-01-10 16:20 ` Pablo Neira Ayuso
0 siblings, 0 replies; 13+ messages in thread
From: Pablo Neira Ayuso @ 2013-01-10 16:20 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, tomasz.bursztyka
On Thu, Jan 10, 2013 at 05:09:13PM +0100, Patrick McHardy wrote:
> On Thu, Jan 10, 2013 at 04:28:38PM +0100, pablo@netfilter.org wrote:
> > From: Pablo Neira Ayuso <pablo@netfilter.org>
> >
> > This patch moves the struct xt_action_param to struct nft_pktinfo
> > and that structure is filled at the beginning of the every chain.
> >
> > The specific code to handle IPv4 and IPv6 now resides in
> > nf_tables_ipv[4|6].
> >
> > +extern unsigned int nft_do_chain_pktinfo(struct nft_pktinfo *pkt,
> > + const struct nf_hook_ops *ops);
>
> Passing the pktinfo is something I also need to fix the transport layer
> parsing. I don't like that function name at all though, just keep
> nft_do_chain()?
Will change it back to use nft_do_chain.
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2013-01-10 16:20 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-10 15:28 [PATCH 1/7] netfilter: nf_tables: nft_compat: release cached matches/targets pablo
2013-01-10 15:28 ` [PATCH 2/7] netfilter: nf_tables: move filter chain definition to layer 3 modules pablo
2013-01-10 16:02 ` Patrick McHardy
2013-01-10 15:28 ` [PATCH 3/7] netfilter: nf_tables: remove hook definitions from struct nft_af_info pablo
2013-01-10 16:04 ` Patrick McHardy
2013-01-10 16:19 ` Pablo Neira Ayuso
2013-01-10 15:28 ` [PATCH 4/7] netfilter: nf_tables: move specific layer 3 compat code to nf_tables_ipv[4|6] pablo
2013-01-10 16:09 ` Patrick McHardy
2013-01-10 16:20 ` Pablo Neira Ayuso
2013-01-10 15:28 ` [PATCH 5/7] netfilter: nf_tables: x_tables support as a compile time option pablo
2013-01-10 15:28 ` [PATCH 6/7] netfilter: nf_tables: support 32bits-64bits x_tables compat pablo
2013-01-10 16:12 ` Patrick McHardy
2013-01-10 15:28 ` [PATCH 7/7] netfilter: nf_tables: fix alias for xtables over nftables module pablo
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.