* [PATCH 00/23] nf_tables updates for net-next
@ 2014-01-10 0:35 Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 01/23] netfilter: nft_reject: fix compilation warning if NF_TABLES_IPV6 is disabled Pablo Neira Ayuso
` (23 more replies)
0 siblings, 24 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
Hi David,
The following patchset contains the following nf_tables updates,
mostly updates from Patrick McHardy, they are:
* Add the "inet" table and filter chain type for this new netfilter
family: NFPROTO_INET. This special table/chain allows IPv4 and IPv6
rules, this should help to simplify the burden in the administration
of dual stack firewalls. This also includes several patches to prepare
the infrastructure for this new table and a new meta extension to
match the layer 3 and 4 protocol numbers, from Patrick McHardy.
* Load both IPv4 and IPv6 conntrack modules in nft_ct if the rule is used
in NFPROTO_INET, as we don't certainly know which one would be used,
also from Patrick McHardy.
* Do not allow to delete a table that contains sets, otherwise these
sets become orphan, from Patrick McHardy.
* Hold a reference to the corresponding nf_tables family module when
creating a table of that family type, to avoid the module deletion
when in use, from Patrick McHardy.
* Update chain counters before setting the chain policy to ensure that
we don't leave the chain in inconsistent state in case of errors (aka.
restore chain atomicity). This also fixes a possible leak if it fails
to allocate the chain counters if no counters are passed to be restored,
from Patrick McHardy.
* Don't check for overflows in the table counter if we are just renaming
a chain, from Patrick McHardy.
* Replay the netlink request after dropping the nfnl lock to load the
module that supports provides a chain type, from Patrick.
* Fix chain type module references, from Patrick.
* Several cleanups, function renames, constification and code
refactorizations also from Patrick McHardy.
* Add support to set the connmark, this can be used to set it based on
the meta mark (similar feature to -j CONNMARK --restore), from
Kristian Evensen.
* A couple of fixes to the recently added meta/set support and nft_reject,
and fix missing chain type unregistration if we fail to register our
the family table/filter chain type, from myself.
You can pull these changes from:
git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nftables.git master
Thanks!
----------------------------------------------------------------
The following changes since commit cdb3f4a31b64c3a1c6eef40bc01ebc9594c58a8c:
net: Do not enable tx-nocache-copy by default (2014-01-07 16:20:19 -0500)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nftables.git master
for you to fetch changes up to cf4dfa85395ebe2769267a072b39e48301669842:
netfilter: nf_tables: fix error path in the init functions (2014-01-09 23:25:48 +0100)
----------------------------------------------------------------
Kristian Evensen (1):
netfilter: nft_ct: Add support to set the connmark
Pablo Neira Ayuso (3):
netfilter: nft_reject: fix compilation warning if NF_TABLES_IPV6 is disabled
netfilter: nft_meta: fix lack of validation of the input register
netfilter: nf_tables: fix error path in the init functions
Patrick McHardy (19):
netfilter: nf_tables: make chain types override the default AF functions
netfilter: nf_tables: add hook ops to struct nft_pktinfo
netfilter: nf_tables: add support for multi family tables
netfilter: nf_tables: add "inet" table for IPv4/IPv6
netfilter: nf_tables: add nfproto support to meta expression
netfilter: nft_meta: add l4proto support
netfilter: nft_ct: load both IPv4 and IPv6 conntrack modules for NFPROTO_INET
netfilter: nf_tables: split chain policy validation from actually setting it
netfilter: nf_tables: restore chain change atomicity
netfilter: nf_tables: fix check for table overflow
netfilter: nf_tables: fix chain type module reference handling
netfilter: nf_tables: add missing module references to chain types
netfilter: nf_tables: replay request after dropping locks to load chain type
netfilter: nf_tables: constify chain type definitions and pointers
netfilter: nf_tables: minor nf_chain_type cleanups
netfilter: nf_tables: perform flags validation before table allocation
netfilter: nf_tables: take AF module reference when creating a table
netfilter: nf_tables: prohibit deletion of a table with existing sets
netfilter: nf_tables: rename nft_do_chain_pktinfo() to nft_do_chain()
include/net/netfilter/nf_tables.h | 47 ++++--
include/net/netfilter/nf_tables_ipv4.h | 5 +-
include/net/netfilter/nf_tables_ipv6.h | 3 +
include/net/netns/nftables.h | 1 +
include/uapi/linux/netfilter.h | 1 +
include/uapi/linux/netfilter/nf_tables.h | 6 +
net/bridge/netfilter/nf_tables_bridge.c | 44 +++---
net/ipv4/netfilter/nf_tables_arp.c | 44 +++---
net/ipv4/netfilter/nf_tables_ipv4.c | 60 ++++----
net/ipv4/netfilter/nft_chain_nat_ipv4.c | 10 +-
net/ipv4/netfilter/nft_chain_route_ipv4.c | 10 +-
net/ipv6/netfilter/nf_tables_ipv6.c | 65 ++++-----
net/ipv6/netfilter/nft_chain_nat_ipv6.c | 10 +-
net/ipv6/netfilter/nft_chain_route_ipv6.c | 10 +-
net/netfilter/Kconfig | 8 ++
net/netfilter/Makefile | 1 +
net/netfilter/nf_tables_api.c | 223 +++++++++++++++--------------
net/netfilter/nf_tables_core.c | 6 +-
net/netfilter/nf_tables_inet.c | 104 ++++++++++++++
net/netfilter/nft_compat.c | 8 +-
net/netfilter/nft_ct.c | 199 +++++++++++++++++++++----
net/netfilter/nft_log.c | 2 +-
net/netfilter/nft_meta.c | 11 ++
net/netfilter/nft_reject.c | 9 +-
24 files changed, 595 insertions(+), 292 deletions(-)
create mode 100644 net/netfilter/nf_tables_inet.c
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH 01/23] netfilter: nft_reject: fix compilation warning if NF_TABLES_IPV6 is disabled
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 20:33 ` Sergei Shtylyov
2014-01-10 0:35 ` [PATCH 02/23] netfilter: nf_tables: make chain types override the default AF functions Pablo Neira Ayuso
` (22 subsequent siblings)
23 siblings, 1 reply; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
net/netfilter/nft_reject.c: In function 'nft_reject_eval':
net/netfilter/nft_reject.c:37:14: warning: unused variable 'net' [-Wunused-variable]
Reported-by: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nft_reject.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/netfilter/nft_reject.c b/net/netfilter/nft_reject.c
index 0d690d4..7ae63cd 100644
--- a/net/netfilter/nft_reject.c
+++ b/net/netfilter/nft_reject.c
@@ -34,8 +34,9 @@ static void nft_reject_eval(const struct nft_expr *expr,
const struct nft_pktinfo *pkt)
{
struct nft_reject *priv = nft_expr_priv(expr);
+#if IS_ENABLED(CONFIG_NF_TABLES_IPV6)
struct net *net = dev_net((pkt->in != NULL) ? pkt->in : pkt->out);
-
+#endif
switch (priv->type) {
case NFT_REJECT_ICMP_UNREACH:
if (priv->family == NFPROTO_IPV4)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 02/23] netfilter: nf_tables: make chain types override the default AF functions
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 01/23] netfilter: nft_reject: fix compilation warning if NF_TABLES_IPV6 is disabled Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 03/23] netfilter: nf_tables: add hook ops to struct nft_pktinfo Pablo Neira Ayuso
` (21 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Currently the AF-specific hook functions override the chain-type specific
hook functions. That doesn't make too much sense since the chain types
are a special case of the AF-specific hooks.
Make the AF-specific hook functions the default and make the optional
chain type hooks override them.
As a side effect, the necessary code restructuring reduces the code size,
f.i. in case of nf_tables_ipv4.o:
nf_tables_ipv4_init_net | -24
nft_do_chain_ipv4 | -113
2 functions changed, 137 bytes removed, diff: -137
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/bridge/netfilter/nf_tables_bridge.c | 38 ++++++++++++------------
net/ipv4/netfilter/nf_tables_arp.c | 38 ++++++++++++------------
net/ipv4/netfilter/nf_tables_ipv4.c | 43 ++++++++++++---------------
net/ipv6/netfilter/nf_tables_ipv6.c | 48 +++++++++++++------------------
net/netfilter/nf_tables_api.c | 10 +++----
5 files changed, 81 insertions(+), 96 deletions(-)
diff --git a/net/bridge/netfilter/nf_tables_bridge.c b/net/bridge/netfilter/nf_tables_bridge.c
index cf54b22..c5fdd9a 100644
--- a/net/bridge/netfilter/nf_tables_bridge.c
+++ b/net/bridge/netfilter/nf_tables_bridge.c
@@ -14,10 +14,29 @@
#include <linux/netfilter_bridge.h>
#include <net/netfilter/nf_tables.h>
+static unsigned int
+nft_do_chain_bridge(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(&pkt, ops, skb, in, out);
+
+ return nft_do_chain_pktinfo(&pkt, ops);
+}
+
static struct nft_af_info nft_af_bridge __read_mostly = {
.family = NFPROTO_BRIDGE,
.nhooks = NF_BR_NUMHOOKS,
.owner = THIS_MODULE,
+ .hooks = {
+ [NF_BR_LOCAL_IN] = nft_do_chain_bridge,
+ [NF_BR_FORWARD] = nft_do_chain_bridge,
+ [NF_BR_LOCAL_OUT] = nft_do_chain_bridge,
+ },
};
static int nf_tables_bridge_init_net(struct net *net)
@@ -48,20 +67,6 @@ static struct pernet_operations nf_tables_bridge_net_ops = {
.exit = nf_tables_bridge_exit_net,
};
-static unsigned int
-nft_do_chain_bridge(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(&pkt, ops, skb, in, out);
-
- return nft_do_chain_pktinfo(&pkt, ops);
-}
-
static struct nf_chain_type filter_bridge = {
.family = NFPROTO_BRIDGE,
.name = "filter",
@@ -69,11 +74,6 @@ static struct nf_chain_type filter_bridge = {
.hook_mask = (1 << NF_BR_LOCAL_IN) |
(1 << NF_BR_FORWARD) |
(1 << NF_BR_LOCAL_OUT),
- .fn = {
- [NF_BR_LOCAL_IN] = nft_do_chain_bridge,
- [NF_BR_FORWARD] = nft_do_chain_bridge,
- [NF_BR_LOCAL_OUT] = nft_do_chain_bridge,
- },
};
static int __init nf_tables_bridge_init(void)
diff --git a/net/ipv4/netfilter/nf_tables_arp.c b/net/ipv4/netfilter/nf_tables_arp.c
index 3e67ef1..31bb778 100644
--- a/net/ipv4/netfilter/nf_tables_arp.c
+++ b/net/ipv4/netfilter/nf_tables_arp.c
@@ -14,10 +14,29 @@
#include <linux/netfilter_arp.h>
#include <net/netfilter/nf_tables.h>
+static unsigned int
+nft_do_chain_arp(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(&pkt, ops, skb, in, out);
+
+ return nft_do_chain_pktinfo(&pkt, ops);
+}
+
static struct nft_af_info nft_af_arp __read_mostly = {
.family = NFPROTO_ARP,
.nhooks = NF_ARP_NUMHOOKS,
.owner = THIS_MODULE,
+ .hooks = {
+ [NF_ARP_IN] = nft_do_chain_arp,
+ [NF_ARP_OUT] = nft_do_chain_arp,
+ [NF_ARP_FORWARD] = nft_do_chain_arp,
+ },
};
static int nf_tables_arp_init_net(struct net *net)
@@ -48,20 +67,6 @@ static struct pernet_operations nf_tables_arp_net_ops = {
.exit = nf_tables_arp_exit_net,
};
-static unsigned int
-nft_do_chain_arp(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(&pkt, ops, skb, in, out);
-
- return nft_do_chain_pktinfo(&pkt, ops);
-}
-
static struct nf_chain_type filter_arp = {
.family = NFPROTO_ARP,
.name = "filter",
@@ -69,11 +74,6 @@ static struct nf_chain_type filter_arp = {
.hook_mask = (1 << NF_ARP_IN) |
(1 << NF_ARP_OUT) |
(1 << NF_ARP_FORWARD),
- .fn = {
- [NF_ARP_IN] = nft_do_chain_arp,
- [NF_ARP_OUT] = nft_do_chain_arp,
- [NF_ARP_FORWARD] = nft_do_chain_arp,
- },
};
static int __init nf_tables_arp_init(void)
diff --git a/net/ipv4/netfilter/nf_tables_ipv4.c b/net/ipv4/netfilter/nf_tables_ipv4.c
index 0f4cbfe..ed7e15a 100644
--- a/net/ipv4/netfilter/nf_tables_ipv4.c
+++ b/net/ipv4/netfilter/nf_tables_ipv4.c
@@ -18,14 +18,25 @@
#include <net/ip.h>
#include <net/netfilter/nf_tables_ipv4.h>
+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 unsigned int nft_ipv4_output(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;
-
if (unlikely(skb->len < sizeof(struct iphdr) ||
ip_hdr(skb)->ihl < sizeof(struct iphdr) / 4)) {
if (net_ratelimit())
@@ -33,9 +44,8 @@ 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_pktinfo(&pkt, ops);
+ return nft_do_chain_ipv4(ops, skb, in, out, okfn);
}
static struct nft_af_info nft_af_ipv4 __read_mostly = {
@@ -43,7 +53,11 @@ static struct nft_af_info nft_af_ipv4 __read_mostly = {
.nhooks = NF_INET_NUMHOOKS,
.owner = THIS_MODULE,
.hooks = {
+ [NF_INET_LOCAL_IN] = nft_do_chain_ipv4,
[NF_INET_LOCAL_OUT] = nft_ipv4_output,
+ [NF_INET_FORWARD] = nft_do_chain_ipv4,
+ [NF_INET_PRE_ROUTING] = nft_do_chain_ipv4,
+ [NF_INET_POST_ROUTING] = nft_do_chain_ipv4,
},
};
@@ -75,20 +89,6 @@ 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",
@@ -98,13 +98,6 @@ static struct nf_chain_type filter_ipv4 = {
(1 << NF_INET_FORWARD) |
(1 << NF_INET_PRE_ROUTING) |
(1 << NF_INET_POST_ROUTING),
- .fn = {
- [NF_INET_LOCAL_IN] = nft_do_chain_ipv4,
- [NF_INET_LOCAL_OUT] = nft_ipv4_output,
- [NF_INET_FORWARD] = nft_do_chain_ipv4,
- [NF_INET_PRE_ROUTING] = nft_do_chain_ipv4,
- [NF_INET_POST_ROUTING] = nft_do_chain_ipv4,
- },
};
static int __init nf_tables_ipv4_init(void)
diff --git a/net/ipv6/netfilter/nf_tables_ipv6.c b/net/ipv6/netfilter/nf_tables_ipv6.c
index d77db8a..54a2bcd 100644
--- a/net/ipv6/netfilter/nf_tables_ipv6.c
+++ b/net/ipv6/netfilter/nf_tables_ipv6.c
@@ -16,24 +16,35 @@
#include <net/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables_ipv6.h>
+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 unsigned int nft_ipv6_output(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;
-
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_pktinfo(&pkt, ops);
+ return nft_do_chain_ipv6(ops, skb, in, out, okfn);
}
static struct nft_af_info nft_af_ipv6 __read_mostly = {
@@ -41,7 +52,11 @@ static struct nft_af_info nft_af_ipv6 __read_mostly = {
.nhooks = NF_INET_NUMHOOKS,
.owner = THIS_MODULE,
.hooks = {
+ [NF_INET_LOCAL_IN] = nft_do_chain_ipv6,
[NF_INET_LOCAL_OUT] = nft_ipv6_output,
+ [NF_INET_FORWARD] = nft_do_chain_ipv6,
+ [NF_INET_PRE_ROUTING] = nft_do_chain_ipv6,
+ [NF_INET_POST_ROUTING] = nft_do_chain_ipv6,
},
};
@@ -73,22 +88,6 @@ 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",
@@ -98,13 +97,6 @@ static struct nf_chain_type filter_ipv6 = {
(1 << NF_INET_FORWARD) |
(1 << NF_INET_PRE_ROUTING) |
(1 << NF_INET_POST_ROUTING),
- .fn = {
- [NF_INET_LOCAL_IN] = nft_do_chain_ipv6,
- [NF_INET_LOCAL_OUT] = nft_ipv6_output,
- [NF_INET_FORWARD] = nft_do_chain_ipv6,
- [NF_INET_PRE_ROUTING] = nft_do_chain_ipv6,
- [NF_INET_POST_ROUTING] = nft_do_chain_ipv6,
- },
};
static int __init nf_tables_ipv6_init(void)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 1fcef1e..d568626 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -927,9 +927,9 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
if (hooknum >= afi->nhooks)
return -EINVAL;
- hookfn = chain_type[family][type]->fn[hooknum];
- if (hookfn == NULL)
+ if (!(chain_type[family][type]->hook_mask & (1 << hooknum)))
return -EOPNOTSUPP;
+ hookfn = chain_type[family][type]->fn[hooknum];
basechain = kzalloc(sizeof(*basechain), GFP_KERNEL);
if (basechain == NULL)
@@ -944,9 +944,9 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
ops->hooknum = ntohl(nla_get_be32(ha[NFTA_HOOK_HOOKNUM]));
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];
+ ops->hook = afi->hooks[ops->hooknum];
+ if (hookfn)
+ ops->hook = hookfn;
chain->flags |= NFT_BASE_CHAIN;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 03/23] netfilter: nf_tables: add hook ops to struct nft_pktinfo
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 01/23] netfilter: nft_reject: fix compilation warning if NF_TABLES_IPV6 is disabled Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 02/23] netfilter: nf_tables: make chain types override the default AF functions Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 04/23] netfilter: nf_tables: add support for multi family tables Pablo Neira Ayuso
` (20 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Multi-family tables need the AF from the hook ops. Add a pointer to the
hook ops and replace usage of the hooknum member in struct nft_pktinfo.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 5 +++--
net/netfilter/nf_tables_core.c | 2 +-
net/netfilter/nft_log.c | 2 +-
net/netfilter/nft_reject.c | 6 +++---
4 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 5a91abf..c9e6316 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -13,7 +13,7 @@ struct nft_pktinfo {
struct sk_buff *skb;
const struct net_device *in;
const struct net_device *out;
- u8 hooknum;
+ const struct nf_hook_ops *ops;
u8 nhoff;
u8 thoff;
/* for x_tables compatibility */
@@ -29,7 +29,8 @@ static inline void nft_set_pktinfo(struct nft_pktinfo *pkt,
pkt->skb = skb;
pkt->in = pkt->xt.in = in;
pkt->out = pkt->xt.out = out;
- pkt->hooknum = pkt->xt.hooknum = ops->hooknum;
+ pkt->ops = ops;
+ pkt->xt.hooknum = ops->hooknum;
pkt->xt.family = ops->pf;
}
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c
index e8fcc34..5aae317 100644
--- a/net/netfilter/nf_tables_core.c
+++ b/net/netfilter/nf_tables_core.c
@@ -109,7 +109,7 @@ static inline void nft_trace_packet(const struct nft_pktinfo *pkt,
{
struct net *net = dev_net(pkt->in ? pkt->in : pkt->out);
- nf_log_packet(net, pkt->xt.family, pkt->hooknum, pkt->skb, pkt->in,
+ nf_log_packet(net, pkt->xt.family, pkt->ops->hooknum, pkt->skb, pkt->in,
pkt->out, &trace_loginfo, "TRACE: %s:%s:%s:%u ",
chain->table->name, chain->name, comments[type],
rulenum);
diff --git a/net/netfilter/nft_log.c b/net/netfilter/nft_log.c
index 57cad07..5af7901 100644
--- a/net/netfilter/nft_log.c
+++ b/net/netfilter/nft_log.c
@@ -33,7 +33,7 @@ static void nft_log_eval(const struct nft_expr *expr,
const struct nft_log *priv = nft_expr_priv(expr);
struct net *net = dev_net(pkt->in ? pkt->in : pkt->out);
- nf_log_packet(net, priv->family, pkt->hooknum, pkt->skb, pkt->in,
+ nf_log_packet(net, priv->family, pkt->ops->hooknum, pkt->skb, pkt->in,
pkt->out, &priv->loginfo, "%s", priv->prefix);
}
diff --git a/net/netfilter/nft_reject.c b/net/netfilter/nft_reject.c
index 7ae63cd..5e204711 100644
--- a/net/netfilter/nft_reject.c
+++ b/net/netfilter/nft_reject.c
@@ -44,15 +44,15 @@ static void nft_reject_eval(const struct nft_expr *expr,
#if IS_ENABLED(CONFIG_NF_TABLES_IPV6)
else if (priv->family == NFPROTO_IPV6)
nf_send_unreach6(net, pkt->skb, priv->icmp_code,
- pkt->hooknum);
+ pkt->ops->hooknum);
#endif
break;
case NFT_REJECT_TCP_RST:
if (priv->family == NFPROTO_IPV4)
- nf_send_reset(pkt->skb, pkt->hooknum);
+ nf_send_reset(pkt->skb, pkt->ops->hooknum);
#if IS_ENABLED(CONFIG_NF_TABLES_IPV6)
else if (priv->family == NFPROTO_IPV6)
- nf_send_reset6(net, pkt->skb, pkt->hooknum);
+ nf_send_reset6(net, pkt->skb, pkt->ops->hooknum);
#endif
break;
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 04/23] netfilter: nf_tables: add support for multi family tables
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
` (2 preceding siblings ...)
2014-01-10 0:35 ` [PATCH 03/23] netfilter: nf_tables: add hook ops to struct nft_pktinfo Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 05/23] netfilter: nf_tables: add "inet" table for IPv4/IPv6 Pablo Neira Ayuso
` (19 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Add support to register chains to multiple hooks for different address
families for mixed IPv4/IPv6 tables.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
include/net/netfilter/nf_tables.h | 9 +++++-
net/bridge/netfilter/nf_tables_bridge.c | 1 +
net/ipv4/netfilter/nf_tables_arp.c | 1 +
net/ipv4/netfilter/nf_tables_ipv4.c | 1 +
net/ipv6/netfilter/nf_tables_ipv6.c | 1 +
net/netfilter/nf_tables_api.c | 49 ++++++++++++++++++-------------
net/netfilter/nft_compat.c | 8 ++---
7 files changed, 45 insertions(+), 25 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index c9e6316..f066f25 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -422,6 +422,8 @@ struct nft_stats {
u64 pkts;
};
+#define NFT_HOOK_OPS_MAX 2
+
/**
* struct nft_base_chain - nf_tables base chain
*
@@ -432,7 +434,7 @@ struct nft_stats {
* @chain: the chain
*/
struct nft_base_chain {
- struct nf_hook_ops ops;
+ struct nf_hook_ops ops[NFT_HOOK_OPS_MAX];
enum nft_chain_type type;
u8 policy;
struct nft_stats __percpu *stats;
@@ -476,6 +478,8 @@ struct nft_table {
* @nhooks: number of hooks in this family
* @owner: module owner
* @tables: used internally
+ * @nops: number of hook ops in this family
+ * @hook_ops_init: initialization function for chain hook ops
* @hooks: hookfn overrides for packet validation
*/
struct nft_af_info {
@@ -484,6 +488,9 @@ struct nft_af_info {
unsigned int nhooks;
struct module *owner;
struct list_head tables;
+ unsigned int nops;
+ void (*hook_ops_init)(struct nf_hook_ops *,
+ unsigned int);
nf_hookfn *hooks[NF_MAX_HOOKS];
};
diff --git a/net/bridge/netfilter/nf_tables_bridge.c b/net/bridge/netfilter/nf_tables_bridge.c
index c5fdd9a..003c1e9 100644
--- a/net/bridge/netfilter/nf_tables_bridge.c
+++ b/net/bridge/netfilter/nf_tables_bridge.c
@@ -32,6 +32,7 @@ static struct nft_af_info nft_af_bridge __read_mostly = {
.family = NFPROTO_BRIDGE,
.nhooks = NF_BR_NUMHOOKS,
.owner = THIS_MODULE,
+ .nops = 1,
.hooks = {
[NF_BR_LOCAL_IN] = nft_do_chain_bridge,
[NF_BR_FORWARD] = nft_do_chain_bridge,
diff --git a/net/ipv4/netfilter/nf_tables_arp.c b/net/ipv4/netfilter/nf_tables_arp.c
index 31bb778..36d27fc 100644
--- a/net/ipv4/netfilter/nf_tables_arp.c
+++ b/net/ipv4/netfilter/nf_tables_arp.c
@@ -32,6 +32,7 @@ static struct nft_af_info nft_af_arp __read_mostly = {
.family = NFPROTO_ARP,
.nhooks = NF_ARP_NUMHOOKS,
.owner = THIS_MODULE,
+ .nops = 1,
.hooks = {
[NF_ARP_IN] = nft_do_chain_arp,
[NF_ARP_OUT] = nft_do_chain_arp,
diff --git a/net/ipv4/netfilter/nf_tables_ipv4.c b/net/ipv4/netfilter/nf_tables_ipv4.c
index ed7e15a..177c3bc 100644
--- a/net/ipv4/netfilter/nf_tables_ipv4.c
+++ b/net/ipv4/netfilter/nf_tables_ipv4.c
@@ -52,6 +52,7 @@ static struct nft_af_info nft_af_ipv4 __read_mostly = {
.family = NFPROTO_IPV4,
.nhooks = NF_INET_NUMHOOKS,
.owner = THIS_MODULE,
+ .nops = 1,
.hooks = {
[NF_INET_LOCAL_IN] = nft_do_chain_ipv4,
[NF_INET_LOCAL_OUT] = nft_ipv4_output,
diff --git a/net/ipv6/netfilter/nf_tables_ipv6.c b/net/ipv6/netfilter/nf_tables_ipv6.c
index 54a2bcd..642280e 100644
--- a/net/ipv6/netfilter/nf_tables_ipv6.c
+++ b/net/ipv6/netfilter/nf_tables_ipv6.c
@@ -51,6 +51,7 @@ static struct nft_af_info nft_af_ipv6 __read_mostly = {
.family = NFPROTO_IPV6,
.nhooks = NF_INET_NUMHOOKS,
.owner = THIS_MODULE,
+ .nops = 1,
.hooks = {
[NF_INET_LOCAL_IN] = nft_do_chain_ipv6,
[NF_INET_LOCAL_OUT] = nft_ipv6_output,
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index d568626..572d88d 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -307,7 +307,8 @@ err:
return err;
}
-static int nf_tables_table_enable(struct nft_table *table)
+static int nf_tables_table_enable(const struct nft_af_info *afi,
+ struct nft_table *table)
{
struct nft_chain *chain;
int err, i = 0;
@@ -316,7 +317,7 @@ static int nf_tables_table_enable(struct nft_table *table)
if (!(chain->flags & NFT_BASE_CHAIN))
continue;
- err = nf_register_hook(&nft_base_chain(chain)->ops);
+ err = nf_register_hooks(nft_base_chain(chain)->ops, afi->nops);
if (err < 0)
goto err;
@@ -331,18 +332,20 @@ err:
if (i-- <= 0)
break;
- nf_unregister_hook(&nft_base_chain(chain)->ops);
+ nf_unregister_hooks(nft_base_chain(chain)->ops, afi->nops);
}
return err;
}
-static int nf_tables_table_disable(struct nft_table *table)
+static int nf_tables_table_disable(const struct nft_af_info *afi,
+ struct nft_table *table)
{
struct nft_chain *chain;
list_for_each_entry(chain, &table->chains, list) {
if (chain->flags & NFT_BASE_CHAIN)
- nf_unregister_hook(&nft_base_chain(chain)->ops);
+ nf_unregister_hooks(nft_base_chain(chain)->ops,
+ afi->nops);
}
return 0;
@@ -365,12 +368,12 @@ static int nf_tables_updtable(struct sock *nlsk, struct sk_buff *skb,
if ((flags & NFT_TABLE_F_DORMANT) &&
!(table->flags & NFT_TABLE_F_DORMANT)) {
- ret = nf_tables_table_disable(table);
+ ret = nf_tables_table_disable(afi, table);
if (ret >= 0)
table->flags |= NFT_TABLE_F_DORMANT;
} else if (!(flags & NFT_TABLE_F_DORMANT) &&
table->flags & NFT_TABLE_F_DORMANT) {
- ret = nf_tables_table_enable(table);
+ ret = nf_tables_table_enable(afi, table);
if (ret >= 0)
table->flags &= ~NFT_TABLE_F_DORMANT;
}
@@ -598,7 +601,7 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, u32 portid, u32 seq,
if (chain->flags & NFT_BASE_CHAIN) {
const struct nft_base_chain *basechain = nft_base_chain(chain);
- const struct nf_hook_ops *ops = &basechain->ops;
+ const struct nf_hook_ops *ops = &basechain->ops[0];
struct nlattr *nest;
nest = nla_nest_start(skb, NFTA_CHAIN_HOOK);
@@ -832,6 +835,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
struct net *net = sock_net(skb->sk);
int family = nfmsg->nfgen_family;
u64 handle = 0;
+ unsigned int i;
int err;
bool create;
@@ -904,7 +908,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
if (nla[NFTA_CHAIN_HOOK]) {
struct nf_hook_ops *ops;
nf_hookfn *hookfn;
- u32 hooknum;
+ u32 hooknum, priority;
int type = NFT_CHAIN_T_DEFAULT;
if (nla[NFTA_CHAIN_TYPE]) {
@@ -926,6 +930,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
hooknum = ntohl(nla_get_be32(ha[NFTA_HOOK_HOOKNUM]));
if (hooknum >= afi->nhooks)
return -EINVAL;
+ priority = ntohl(nla_get_be32(ha[NFTA_HOOK_PRIORITY]));
if (!(chain_type[family][type]->hook_mask & (1 << hooknum)))
return -EOPNOTSUPP;
@@ -938,15 +943,19 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
basechain->type = type;
chain = &basechain->chain;
- ops = &basechain->ops;
- ops->pf = family;
- ops->owner = afi->owner;
- ops->hooknum = ntohl(nla_get_be32(ha[NFTA_HOOK_HOOKNUM]));
- ops->priority = ntohl(nla_get_be32(ha[NFTA_HOOK_PRIORITY]));
- ops->priv = chain;
- ops->hook = afi->hooks[ops->hooknum];
- if (hookfn)
- ops->hook = hookfn;
+ for (i = 0; i < afi->nops; i++) {
+ ops = &basechain->ops[i];
+ ops->pf = family;
+ ops->owner = afi->owner;
+ ops->hooknum = hooknum;
+ ops->priority = priority;
+ ops->priv = chain;
+ ops->hook = afi->hooks[ops->hooknum];
+ if (hookfn)
+ ops->hook = hookfn;
+ if (afi->hook_ops_init)
+ afi->hook_ops_init(ops, i);
+ }
chain->flags |= NFT_BASE_CHAIN;
@@ -993,7 +1002,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
if (!(table->flags & NFT_TABLE_F_DORMANT) &&
chain->flags & NFT_BASE_CHAIN) {
- err = nf_register_hook(&nft_base_chain(chain)->ops);
+ err = nf_register_hooks(nft_base_chain(chain)->ops, afi->nops);
if (err < 0) {
free_percpu(basechain->stats);
kfree(basechain);
@@ -1052,7 +1061,7 @@ static int nf_tables_delchain(struct sock *nlsk, struct sk_buff *skb,
if (!(table->flags & NFT_TABLE_F_DORMANT) &&
chain->flags & NFT_BASE_CHAIN)
- nf_unregister_hook(&nft_base_chain(chain)->ops);
+ nf_unregister_hooks(nft_base_chain(chain)->ops, afi->nops);
nf_tables_chain_notify(skb, nlh, table, chain, NFT_MSG_DELCHAIN,
family);
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c
index da0c1f4..82cb823 100644
--- a/net/netfilter/nft_compat.c
+++ b/net/netfilter/nft_compat.c
@@ -92,7 +92,7 @@ nft_target_set_tgchk_param(struct xt_tgchk_param *par,
if (ctx->chain->flags & NFT_BASE_CHAIN) {
const struct nft_base_chain *basechain =
nft_base_chain(ctx->chain);
- const struct nf_hook_ops *ops = &basechain->ops;
+ const struct nf_hook_ops *ops = &basechain->ops[0];
par->hook_mask = 1 << ops->hooknum;
}
@@ -253,7 +253,7 @@ static int nft_target_validate(const struct nft_ctx *ctx,
if (ctx->chain->flags & NFT_BASE_CHAIN) {
const struct nft_base_chain *basechain =
nft_base_chain(ctx->chain);
- const struct nf_hook_ops *ops = &basechain->ops;
+ const struct nf_hook_ops *ops = &basechain->ops[0];
hook_mask = 1 << ops->hooknum;
if (hook_mask & target->hooks)
@@ -323,7 +323,7 @@ nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx,
if (ctx->chain->flags & NFT_BASE_CHAIN) {
const struct nft_base_chain *basechain =
nft_base_chain(ctx->chain);
- const struct nf_hook_ops *ops = &basechain->ops;
+ const struct nf_hook_ops *ops = &basechain->ops[0];
par->hook_mask = 1 << ops->hooknum;
}
@@ -449,7 +449,7 @@ static int nft_match_validate(const struct nft_ctx *ctx,
if (ctx->chain->flags & NFT_BASE_CHAIN) {
const struct nft_base_chain *basechain =
nft_base_chain(ctx->chain);
- const struct nf_hook_ops *ops = &basechain->ops;
+ const struct nf_hook_ops *ops = &basechain->ops[0];
hook_mask = 1 << ops->hooknum;
if (hook_mask & match->hooks)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 05/23] netfilter: nf_tables: add "inet" table for IPv4/IPv6
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
` (3 preceding siblings ...)
2014-01-10 0:35 ` [PATCH 04/23] netfilter: nf_tables: add support for multi family tables Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 06/23] netfilter: nf_tables: add nfproto support to meta expression Pablo Neira Ayuso
` (18 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
This patch adds a new table family and a new filter chain that you can
use to attach IPv4 and IPv6 rules. This should help to simplify
rule-set maintainance in dual-stack setups.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables_ipv4.h | 2 +
include/net/netfilter/nf_tables_ipv6.h | 2 +
include/net/netns/nftables.h | 1 +
include/uapi/linux/netfilter.h | 1 +
net/ipv4/netfilter/nf_tables_ipv4.c | 3 +-
net/ipv6/netfilter/nf_tables_ipv6.c | 3 +-
net/netfilter/Kconfig | 8 +++
net/netfilter/Makefile | 1 +
net/netfilter/nf_tables_inet.c | 97 ++++++++++++++++++++++++++++++++
9 files changed, 116 insertions(+), 2 deletions(-)
create mode 100644 net/netfilter/nf_tables_inet.c
diff --git a/include/net/netfilter/nf_tables_ipv4.h b/include/net/netfilter/nf_tables_ipv4.h
index 1be1c2c..f7b3a66 100644
--- a/include/net/netfilter/nf_tables_ipv4.h
+++ b/include/net/netfilter/nf_tables_ipv4.h
@@ -20,4 +20,6 @@ nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt,
pkt->xt.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
}
+extern struct nft_af_info nft_af_ipv4;
+
#endif
diff --git a/include/net/netfilter/nf_tables_ipv6.h b/include/net/netfilter/nf_tables_ipv6.h
index 4a9b88a..3d8ae48 100644
--- a/include/net/netfilter/nf_tables_ipv6.h
+++ b/include/net/netfilter/nf_tables_ipv6.h
@@ -27,4 +27,6 @@ nft_set_pktinfo_ipv6(struct nft_pktinfo *pkt,
return 0;
}
+extern struct nft_af_info nft_af_ipv6;
+
#endif
diff --git a/include/net/netns/nftables.h b/include/net/netns/nftables.h
index 15d056d..26a394c 100644
--- a/include/net/netns/nftables.h
+++ b/include/net/netns/nftables.h
@@ -10,6 +10,7 @@ struct netns_nftables {
struct list_head commit_list;
struct nft_af_info *ipv4;
struct nft_af_info *ipv6;
+ struct nft_af_info *inet;
struct nft_af_info *arp;
struct nft_af_info *bridge;
u8 gencursor;
diff --git a/include/uapi/linux/netfilter.h b/include/uapi/linux/netfilter.h
index f7dc0eb..ef1b1f8 100644
--- a/include/uapi/linux/netfilter.h
+++ b/include/uapi/linux/netfilter.h
@@ -53,6 +53,7 @@ enum nf_inet_hooks {
enum {
NFPROTO_UNSPEC = 0,
+ NFPROTO_INET = 1,
NFPROTO_IPV4 = 2,
NFPROTO_ARP = 3,
NFPROTO_BRIDGE = 7,
diff --git a/net/ipv4/netfilter/nf_tables_ipv4.c b/net/ipv4/netfilter/nf_tables_ipv4.c
index 177c3bc..da927dc 100644
--- a/net/ipv4/netfilter/nf_tables_ipv4.c
+++ b/net/ipv4/netfilter/nf_tables_ipv4.c
@@ -48,7 +48,7 @@ static unsigned int nft_ipv4_output(const struct nf_hook_ops *ops,
return nft_do_chain_ipv4(ops, skb, in, out, okfn);
}
-static struct nft_af_info nft_af_ipv4 __read_mostly = {
+struct nft_af_info nft_af_ipv4 __read_mostly = {
.family = NFPROTO_IPV4,
.nhooks = NF_INET_NUMHOOKS,
.owner = THIS_MODULE,
@@ -61,6 +61,7 @@ static struct nft_af_info nft_af_ipv4 __read_mostly = {
[NF_INET_POST_ROUTING] = nft_do_chain_ipv4,
},
};
+EXPORT_SYMBOL_GPL(nft_af_ipv4);
static int nf_tables_ipv4_init_net(struct net *net)
{
diff --git a/net/ipv6/netfilter/nf_tables_ipv6.c b/net/ipv6/netfilter/nf_tables_ipv6.c
index 642280e..025e7f4 100644
--- a/net/ipv6/netfilter/nf_tables_ipv6.c
+++ b/net/ipv6/netfilter/nf_tables_ipv6.c
@@ -47,7 +47,7 @@ static unsigned int nft_ipv6_output(const struct nf_hook_ops *ops,
return nft_do_chain_ipv6(ops, skb, in, out, okfn);
}
-static struct nft_af_info nft_af_ipv6 __read_mostly = {
+struct nft_af_info nft_af_ipv6 __read_mostly = {
.family = NFPROTO_IPV6,
.nhooks = NF_INET_NUMHOOKS,
.owner = THIS_MODULE,
@@ -60,6 +60,7 @@ static struct nft_af_info nft_af_ipv6 __read_mostly = {
[NF_INET_POST_ROUTING] = nft_do_chain_ipv6,
},
};
+EXPORT_SYMBOL_GPL(nft_af_ipv6);
static int nf_tables_ipv6_init_net(struct net *net)
{
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index c3b3b26..37d2092 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -428,6 +428,14 @@ config NF_TABLES
To compile it as a module, choose M here.
+config NF_TABLES_INET
+ depends on NF_TABLES
+ select NF_TABLES_IPV4
+ select NF_TABLES_IPV6
+ tristate "Netfilter nf_tables mixed IPv4/IPv6 tables support"
+ help
+ This option enables support for a mixed IPv4/IPv6 "inet" table.
+
config NFT_EXTHDR
depends on NF_TABLES
tristate "Netfilter nf_tables IPv6 exthdr module"
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 78b4e1c..74c0661 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -70,6 +70,7 @@ 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_NF_TABLES_INET) += nf_tables_inet.o
obj-$(CONFIG_NFT_COMPAT) += nft_compat.o
obj-$(CONFIG_NFT_EXTHDR) += nft_exthdr.o
obj-$(CONFIG_NFT_META) += nft_meta.o
diff --git a/net/netfilter/nf_tables_inet.c b/net/netfilter/nf_tables_inet.c
new file mode 100644
index 0000000..ac0edcb
--- /dev/null
+++ b/net/netfilter/nf_tables_inet.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2012-2014 Patrick McHardy <kaber@trash.net>
+ *
+ * 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
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/ip.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_ipv6.h>
+#include <net/netfilter/nf_tables.h>
+#include <net/netfilter/nf_tables_ipv4.h>
+#include <net/netfilter/nf_tables_ipv6.h>
+#include <net/ip.h>
+
+static void nft_inet_hook_ops_init(struct nf_hook_ops *ops, unsigned int n)
+{
+ struct nft_af_info *afi;
+
+ if (n == 1)
+ afi = &nft_af_ipv4;
+ else
+ afi = &nft_af_ipv6;
+
+ ops->pf = afi->family;
+ if (afi->hooks[ops->hooknum])
+ ops->hook = afi->hooks[ops->hooknum];
+}
+
+static struct nft_af_info nft_af_inet __read_mostly = {
+ .family = NFPROTO_INET,
+ .nhooks = NF_INET_NUMHOOKS,
+ .owner = THIS_MODULE,
+ .nops = 2,
+ .hook_ops_init = nft_inet_hook_ops_init,
+};
+
+static int __net_init nf_tables_inet_init_net(struct net *net)
+{
+ net->nft.inet = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL);
+ if (net->nft.inet == NULL)
+ return -ENOMEM;
+ memcpy(net->nft.inet, &nft_af_inet, sizeof(nft_af_inet));
+
+ if (nft_register_afinfo(net, net->nft.inet) < 0)
+ goto err;
+
+ return 0;
+
+err:
+ kfree(net->nft.inet);
+ return -ENOMEM;
+}
+
+static void __net_exit nf_tables_inet_exit_net(struct net *net)
+{
+ nft_unregister_afinfo(net->nft.inet);
+ kfree(net->nft.inet);
+}
+
+static struct pernet_operations nf_tables_inet_net_ops = {
+ .init = nf_tables_inet_init_net,
+ .exit = nf_tables_inet_exit_net,
+};
+
+static struct nf_chain_type filter_inet = {
+ .family = NFPROTO_INET,
+ .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),
+};
+
+static int __init nf_tables_inet_init(void)
+{
+ nft_register_chain_type(&filter_inet);
+ return register_pernet_subsys(&nf_tables_inet_net_ops);
+}
+
+static void __exit nf_tables_inet_exit(void)
+{
+ unregister_pernet_subsys(&nf_tables_inet_net_ops);
+ nft_unregister_chain_type(&filter_inet);
+}
+
+module_init(nf_tables_inet_init);
+module_exit(nf_tables_inet_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
+MODULE_ALIAS_NFT_FAMILY(1);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 06/23] netfilter: nf_tables: add nfproto support to meta expression
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
` (4 preceding siblings ...)
2014-01-10 0:35 ` [PATCH 05/23] netfilter: nf_tables: add "inet" table for IPv4/IPv6 Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 07/23] netfilter: nft_meta: add l4proto support Pablo Neira Ayuso
` (17 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Needed by multi-family tables to distinguish IPv4 and IPv6 packets.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/uapi/linux/netfilter/nf_tables.h | 2 ++
net/netfilter/nft_meta.c | 4 ++++
2 files changed, 6 insertions(+)
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index aa86a152..10afbfc 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -531,6 +531,7 @@ enum nft_exthdr_attributes {
* @NFT_META_NFTRACE: packet nftrace bit
* @NFT_META_RTCLASSID: realm value of packet's route (skb->dst->tclassid)
* @NFT_META_SECMARK: packet secmark (skb->secmark)
+ * @NFT_META_NFPROTO: netfilter protocol
*/
enum nft_meta_keys {
NFT_META_LEN,
@@ -548,6 +549,7 @@ enum nft_meta_keys {
NFT_META_NFTRACE,
NFT_META_RTCLASSID,
NFT_META_SECMARK,
+ NFT_META_NFPROTO,
};
/**
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 1ceaaa6..999d046 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -43,6 +43,9 @@ static void nft_meta_get_eval(const struct nft_expr *expr,
case NFT_META_PROTOCOL:
*(__be16 *)dest->data = skb->protocol;
break;
+ case NFT_META_NFPROTO:
+ dest->data[0] = pkt->ops->pf;
+ break;
case NFT_META_PRIORITY:
dest->data[0] = skb->priority;
break;
@@ -181,6 +184,7 @@ static int nft_meta_init_validate_get(uint32_t key)
switch (key) {
case NFT_META_LEN:
case NFT_META_PROTOCOL:
+ case NFT_META_NFPROTO:
case NFT_META_PRIORITY:
case NFT_META_MARK:
case NFT_META_IIF:
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 07/23] netfilter: nft_meta: add l4proto support
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
` (5 preceding siblings ...)
2014-01-10 0:35 ` [PATCH 06/23] netfilter: nf_tables: add nfproto support to meta expression Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 08/23] netfilter: nft_ct: load both IPv4 and IPv6 conntrack modules for NFPROTO_INET Pablo Neira Ayuso
` (16 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
For L3-proto independant rules we need to get at the L4 protocol value
directly. Add it to the nft_pktinfo struct and use the meta expression
to retrieve it.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 1 +
include/net/netfilter/nf_tables_ipv4.h | 3 ++-
include/net/netfilter/nf_tables_ipv6.h | 1 +
include/uapi/linux/netfilter/nf_tables.h | 2 ++
net/netfilter/nft_meta.c | 4 ++++
5 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index f066f25..5d2b703 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -16,6 +16,7 @@ struct nft_pktinfo {
const struct nf_hook_ops *ops;
u8 nhoff;
u8 thoff;
+ u8 tprot;
/* for x_tables compatibility */
struct xt_action_param xt;
};
diff --git a/include/net/netfilter/nf_tables_ipv4.h b/include/net/netfilter/nf_tables_ipv4.h
index f7b3a66..cba143f 100644
--- a/include/net/netfilter/nf_tables_ipv4.h
+++ b/include/net/netfilter/nf_tables_ipv4.h
@@ -15,8 +15,9 @@ nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt,
nft_set_pktinfo(pkt, ops, skb, in, out);
- pkt->xt.thoff = ip_hdrlen(pkt->skb);
ip = ip_hdr(pkt->skb);
+ pkt->tprot = ip->protocol;
+ pkt->xt.thoff = ip_hdrlen(pkt->skb);
pkt->xt.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
}
diff --git a/include/net/netfilter/nf_tables_ipv6.h b/include/net/netfilter/nf_tables_ipv6.h
index 3d8ae48..74d9761 100644
--- a/include/net/netfilter/nf_tables_ipv6.h
+++ b/include/net/netfilter/nf_tables_ipv6.h
@@ -21,6 +21,7 @@ nft_set_pktinfo_ipv6(struct nft_pktinfo *pkt,
if (protohdr < 0)
return -1;
+ pkt->tprot = protohdr;
pkt->xt.thoff = thoff;
pkt->xt.fragoff = frag_off;
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 10afbfc..448593c 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -532,6 +532,7 @@ enum nft_exthdr_attributes {
* @NFT_META_RTCLASSID: realm value of packet's route (skb->dst->tclassid)
* @NFT_META_SECMARK: packet secmark (skb->secmark)
* @NFT_META_NFPROTO: netfilter protocol
+ * @NFT_META_L4PROTO: layer 4 protocol number
*/
enum nft_meta_keys {
NFT_META_LEN,
@@ -550,6 +551,7 @@ enum nft_meta_keys {
NFT_META_RTCLASSID,
NFT_META_SECMARK,
NFT_META_NFPROTO,
+ NFT_META_L4PROTO,
};
/**
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 999d046..b43975a 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -46,6 +46,9 @@ static void nft_meta_get_eval(const struct nft_expr *expr,
case NFT_META_NFPROTO:
dest->data[0] = pkt->ops->pf;
break;
+ case NFT_META_L4PROTO:
+ dest->data[0] = pkt->tprot;
+ break;
case NFT_META_PRIORITY:
dest->data[0] = skb->priority;
break;
@@ -185,6 +188,7 @@ static int nft_meta_init_validate_get(uint32_t key)
case NFT_META_LEN:
case NFT_META_PROTOCOL:
case NFT_META_NFPROTO:
+ case NFT_META_L4PROTO:
case NFT_META_PRIORITY:
case NFT_META_MARK:
case NFT_META_IIF:
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 08/23] netfilter: nft_ct: load both IPv4 and IPv6 conntrack modules for NFPROTO_INET
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
` (6 preceding siblings ...)
2014-01-10 0:35 ` [PATCH 07/23] netfilter: nft_meta: add l4proto support Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 20:40 ` Sergei Shtylyov
2014-01-10 0:35 ` [PATCH 09/23] netfilter: nft_ct: Add support to set the connmark Pablo Neira Ayuso
` (15 subsequent siblings)
23 siblings, 1 reply; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
The ct expression can currently not be used in the inet family since
we don't have a conntrack module for NFPROTO_INET, so
nf_ct_l3proto_try_module_get() fails. Add some manual handling to
load the modules for both NFPROTO_IPV4 and NFPROTO_IPV6 if the
ct expression is used in the inet family.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nft_ct.c | 39 ++++++++++++++++++++++++++++++++++++---
1 file changed, 36 insertions(+), 3 deletions(-)
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index 955f4e6..3727a32 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -129,6 +129,39 @@ static const struct nla_policy nft_ct_policy[NFTA_CT_MAX + 1] = {
[NFTA_CT_DIRECTION] = { .type = NLA_U8 },
};
+static int nft_ct_l3proto_try_module_get(uint8_t family)
+{
+ int err;
+
+ if (family == NFPROTO_INET) {
+ err = nf_ct_l3proto_try_module_get(NFPROTO_IPV4);
+ if (err < 0)
+ goto err1;
+ err = nf_ct_l3proto_try_module_get(NFPROTO_IPV6);
+ if (err < 0)
+ goto err2;
+ } else {
+ err = nf_ct_l3proto_try_module_get(family);
+ if (err < 0)
+ goto err1;
+ }
+ return 0;
+
+err2:
+ nf_ct_l3proto_module_put(NFPROTO_IPV4);
+err1:
+ return err;
+}
+
+static void nft_ct_l3proto_module_put(uint8_t family)
+{
+ if (family == NFPROTO_INET) {
+ nf_ct_l3proto_module_put(NFPROTO_IPV4);
+ nf_ct_l3proto_module_put(NFPROTO_IPV6);
+ } else
+ nf_ct_l3proto_module_put(family);
+}
+
static int nft_ct_init(const struct nft_ctx *ctx,
const struct nft_expr *expr,
const struct nlattr * const tb[])
@@ -179,7 +212,7 @@ static int nft_ct_init(const struct nft_ctx *ctx,
return -EOPNOTSUPP;
}
- err = nf_ct_l3proto_try_module_get(ctx->afi->family);
+ err = nft_ct_l3proto_try_module_get(ctx->afi->family);
if (err < 0)
return err;
priv->family = ctx->afi->family;
@@ -195,7 +228,7 @@ static int nft_ct_init(const struct nft_ctx *ctx,
return 0;
err1:
- nf_ct_l3proto_module_put(ctx->afi->family);
+ nft_ct_l3proto_module_put(ctx->afi->family);
return err;
}
@@ -203,7 +236,7 @@ static void nft_ct_destroy(const struct nft_expr *expr)
{
struct nft_ct *priv = nft_expr_priv(expr);
- nf_ct_l3proto_module_put(priv->family);
+ nft_ct_l3proto_module_put(priv->family);
}
static int nft_ct_dump(struct sk_buff *skb, const struct nft_expr *expr)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 09/23] netfilter: nft_ct: Add support to set the connmark
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
` (7 preceding siblings ...)
2014-01-10 0:35 ` [PATCH 08/23] netfilter: nft_ct: load both IPv4 and IPv6 conntrack modules for NFPROTO_INET Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 10/23] netfilter: nft_meta: fix lack of validation of the input register Pablo Neira Ayuso
` (14 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Kristian Evensen <kristian.evensen@gmail.com>
This patch adds kernel support for setting properties of tracked
connections. Currently, only connmark is supported. One use-case
for this feature is to provide the same functionality as
-j CONNMARK --save-mark in iptables.
Some restructuring was needed to implement the set op. The new
structure follows that of nft_meta.
Signed-off-by: Kristian Evensen <kristian.evensen@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/uapi/linux/netfilter/nf_tables.h | 2 +
net/netfilter/nft_ct.c | 164 ++++++++++++++++++++++++------
2 files changed, 136 insertions(+), 30 deletions(-)
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 448593c..83c985a 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -609,12 +609,14 @@ enum nft_ct_keys {
* @NFTA_CT_DREG: destination register (NLA_U32)
* @NFTA_CT_KEY: conntrack data item to load (NLA_U32: nft_ct_keys)
* @NFTA_CT_DIRECTION: direction in case of directional keys (NLA_U8)
+ * @NFTA_CT_SREG: source register (NLA_U32)
*/
enum nft_ct_attributes {
NFTA_CT_UNSPEC,
NFTA_CT_DREG,
NFTA_CT_KEY,
NFTA_CT_DIRECTION,
+ NFTA_CT_SREG,
__NFTA_CT_MAX
};
#define NFTA_CT_MAX (__NFTA_CT_MAX - 1)
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index 3727a32..c7c1285 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -18,17 +18,21 @@
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_tuple.h>
#include <net/netfilter/nf_conntrack_helper.h>
+#include <net/netfilter/nf_conntrack_ecache.h>
struct nft_ct {
enum nft_ct_keys key:8;
enum ip_conntrack_dir dir:8;
- enum nft_registers dreg:8;
+ union{
+ enum nft_registers dreg:8;
+ enum nft_registers sreg:8;
+ };
uint8_t family;
};
-static void nft_ct_eval(const struct nft_expr *expr,
- struct nft_data data[NFT_REG_MAX + 1],
- const struct nft_pktinfo *pkt)
+static void nft_ct_get_eval(const struct nft_expr *expr,
+ struct nft_data data[NFT_REG_MAX + 1],
+ const struct nft_pktinfo *pkt)
{
const struct nft_ct *priv = nft_expr_priv(expr);
struct nft_data *dest = &data[priv->dreg];
@@ -123,10 +127,37 @@ err:
data[NFT_REG_VERDICT].verdict = NFT_BREAK;
}
+static void nft_ct_set_eval(const struct nft_expr *expr,
+ struct nft_data data[NFT_REG_MAX + 1],
+ const struct nft_pktinfo *pkt)
+{
+ const struct nft_ct *priv = nft_expr_priv(expr);
+ struct sk_buff *skb = pkt->skb;
+ u32 value = data[priv->sreg].data[0];
+ enum ip_conntrack_info ctinfo;
+ struct nf_conn *ct;
+
+ ct = nf_ct_get(skb, &ctinfo);
+ if (ct == NULL)
+ return;
+
+ switch (priv->key) {
+#ifdef CONFIG_NF_CONNTRACK_MARK
+ case NFT_CT_MARK:
+ if (ct->mark != value) {
+ ct->mark = value;
+ nf_conntrack_event_cache(IPCT_MARK, ct);
+ }
+ break;
+#endif
+ }
+}
+
static const struct nla_policy nft_ct_policy[NFTA_CT_MAX + 1] = {
[NFTA_CT_DREG] = { .type = NLA_U32 },
[NFTA_CT_KEY] = { .type = NLA_U32 },
[NFTA_CT_DIRECTION] = { .type = NLA_U8 },
+ [NFTA_CT_SREG] = { .type = NLA_U32 },
};
static int nft_ct_l3proto_try_module_get(uint8_t family)
@@ -162,18 +193,11 @@ static void nft_ct_l3proto_module_put(uint8_t family)
nf_ct_l3proto_module_put(family);
}
-static int nft_ct_init(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nlattr * const tb[])
+static int nft_ct_init_validate_get(const struct nft_expr *expr,
+ const struct nlattr * const tb[])
{
struct nft_ct *priv = nft_expr_priv(expr);
- int err;
- if (tb[NFTA_CT_DREG] == NULL ||
- tb[NFTA_CT_KEY] == NULL)
- return -EINVAL;
-
- priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
if (tb[NFTA_CT_DIRECTION] != NULL) {
priv->dir = nla_get_u8(tb[NFTA_CT_DIRECTION]);
switch (priv->dir) {
@@ -212,24 +236,62 @@ static int nft_ct_init(const struct nft_ctx *ctx,
return -EOPNOTSUPP;
}
+ return 0;
+}
+
+static int nft_ct_init_validate_set(uint32_t key)
+{
+ switch (key) {
+ case NFT_CT_MARK:
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int nft_ct_init(const struct nft_ctx *ctx,
+ const struct nft_expr *expr,
+ const struct nlattr * const tb[])
+{
+ struct nft_ct *priv = nft_expr_priv(expr);
+ int err;
+
+ priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
+
+ if (tb[NFTA_CT_DREG]) {
+ err = nft_ct_init_validate_get(expr, tb);
+ if (err < 0)
+ return err;
+
+ priv->dreg = ntohl(nla_get_be32(tb[NFTA_CT_DREG]));
+ err = nft_validate_output_register(priv->dreg);
+ if (err < 0)
+ return err;
+
+ err = nft_validate_data_load(ctx, priv->dreg, NULL,
+ NFT_DATA_VALUE);
+ if (err < 0)
+ return err;
+ } else {
+ err = nft_ct_init_validate_set(priv->key);
+ if (err < 0)
+ return err;
+
+ priv->sreg = ntohl(nla_get_be32(tb[NFTA_CT_SREG]));
+ err = nft_validate_input_register(priv->sreg);
+ if (err < 0)
+ return err;
+ }
+
err = nft_ct_l3proto_try_module_get(ctx->afi->family);
if (err < 0)
return err;
- priv->family = ctx->afi->family;
- priv->dreg = ntohl(nla_get_be32(tb[NFTA_CT_DREG]));
- err = nft_validate_output_register(priv->dreg);
- if (err < 0)
- goto err1;
+ priv->family = ctx->afi->family;
- err = nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
- if (err < 0)
- goto err1;
return 0;
-
-err1:
- nft_ct_l3proto_module_put(ctx->afi->family);
- return err;
}
static void nft_ct_destroy(const struct nft_expr *expr)
@@ -239,7 +301,7 @@ static void nft_ct_destroy(const struct nft_expr *expr)
nft_ct_l3proto_module_put(priv->family);
}
-static int nft_ct_dump(struct sk_buff *skb, const struct nft_expr *expr)
+static int nft_ct_get_dump(struct sk_buff *skb, const struct nft_expr *expr)
{
const struct nft_ct *priv = nft_expr_priv(expr);
@@ -255,19 +317,61 @@ nla_put_failure:
return -1;
}
+static int nft_ct_set_dump(struct sk_buff *skb, const struct nft_expr *expr)
+{
+ const struct nft_ct *priv = nft_expr_priv(expr);
+
+ if (nla_put_be32(skb, NFTA_CT_SREG, htonl(priv->sreg)))
+ goto nla_put_failure;
+ if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key)))
+ goto nla_put_failure;
+ return 0;
+
+nla_put_failure:
+ return -1;
+}
+
static struct nft_expr_type nft_ct_type;
-static const struct nft_expr_ops nft_ct_ops = {
+static const struct nft_expr_ops nft_ct_get_ops = {
.type = &nft_ct_type,
.size = NFT_EXPR_SIZE(sizeof(struct nft_ct)),
- .eval = nft_ct_eval,
+ .eval = nft_ct_get_eval,
.init = nft_ct_init,
.destroy = nft_ct_destroy,
- .dump = nft_ct_dump,
+ .dump = nft_ct_get_dump,
};
+static const struct nft_expr_ops nft_ct_set_ops = {
+ .type = &nft_ct_type,
+ .size = NFT_EXPR_SIZE(sizeof(struct nft_ct)),
+ .eval = nft_ct_set_eval,
+ .init = nft_ct_init,
+ .destroy = nft_ct_destroy,
+ .dump = nft_ct_set_dump,
+};
+
+static const struct nft_expr_ops *
+nft_ct_select_ops(const struct nft_ctx *ctx,
+ const struct nlattr * const tb[])
+{
+ if (tb[NFTA_CT_KEY] == NULL)
+ return ERR_PTR(-EINVAL);
+
+ if (tb[NFTA_CT_DREG] && tb[NFTA_CT_SREG])
+ return ERR_PTR(-EINVAL);
+
+ if (tb[NFTA_CT_DREG])
+ return &nft_ct_get_ops;
+
+ if (tb[NFTA_CT_SREG])
+ return &nft_ct_set_ops;
+
+ return ERR_PTR(-EINVAL);
+}
+
static struct nft_expr_type nft_ct_type __read_mostly = {
.name = "ct",
- .ops = &nft_ct_ops,
+ .select_ops = &nft_ct_select_ops,
.policy = nft_ct_policy,
.maxattr = NFTA_CT_MAX,
.owner = THIS_MODULE,
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 10/23] netfilter: nft_meta: fix lack of validation of the input register
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
` (8 preceding siblings ...)
2014-01-10 0:35 ` [PATCH 09/23] netfilter: nft_ct: Add support to set the connmark Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 11/23] netfilter: nf_tables: split chain policy validation from actually setting it Pablo Neira Ayuso
` (13 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
We have to validate that the input register is in the range of
allowed registers, otherwise we can take a incorrect register
value as input that may lead us to a crash.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nft_meta.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index b43975a..e8254ad 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -239,6 +239,9 @@ static int nft_meta_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
return err;
priv->sreg = ntohl(nla_get_be32(tb[NFTA_META_SREG]));
+ err = nft_validate_input_register(priv->sreg);
+ if (err < 0)
+ return err;
return 0;
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 11/23] netfilter: nf_tables: split chain policy validation from actually setting it
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
` (9 preceding siblings ...)
2014-01-10 0:35 ` [PATCH 10/23] netfilter: nft_meta: fix lack of validation of the input register Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 12/23] netfilter: nf_tables: restore chain change atomicity Pablo Neira Ayuso
` (12 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Currently nf_tables_newchain() atomicity is broken because of having
validation of some netlink attributes performed after changing attributes
of the chain. The chain policy is (currently) fine, but split it up as
preparation for the following fixes and to avoid future mistakes.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_tables_api.c | 56 +++++++++++++++--------------------------
1 file changed, 20 insertions(+), 36 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 572d88d..30fad4f 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -760,22 +760,6 @@ err:
return err;
}
-static int
-nf_tables_chain_policy(struct nft_base_chain *chain, const struct nlattr *attr)
-{
- switch (ntohl(nla_get_be32(attr))) {
- case NF_DROP:
- chain->policy = NF_DROP;
- break;
- case NF_ACCEPT:
- chain->policy = NF_ACCEPT;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
static const struct nla_policy nft_counter_policy[NFTA_COUNTER_MAX + 1] = {
[NFTA_COUNTER_PACKETS] = { .type = NLA_U64 },
[NFTA_COUNTER_BYTES] = { .type = NLA_U64 },
@@ -834,6 +818,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
struct nlattr *ha[NFTA_HOOK_MAX + 1];
struct net *net = sock_net(skb->sk);
int family = nfmsg->nfgen_family;
+ u8 policy = NF_ACCEPT;
u64 handle = 0;
unsigned int i;
int err;
@@ -869,6 +854,22 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
}
}
+ if (nla[NFTA_CHAIN_POLICY]) {
+ if ((chain != NULL &&
+ !(chain->flags & NFT_BASE_CHAIN)) ||
+ nla[NFTA_CHAIN_HOOK] == NULL)
+ return -EOPNOTSUPP;
+
+ policy = nla_get_be32(nla[NFTA_CHAIN_POLICY]);
+ switch (policy) {
+ case NF_DROP:
+ case NF_ACCEPT:
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
if (chain != NULL) {
if (nlh->nlmsg_flags & NLM_F_EXCL)
return -EEXIST;
@@ -879,15 +880,8 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
!IS_ERR(nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME])))
return -EEXIST;
- if (nla[NFTA_CHAIN_POLICY]) {
- if (!(chain->flags & NFT_BASE_CHAIN))
- return -EOPNOTSUPP;
-
- err = nf_tables_chain_policy(nft_base_chain(chain),
- nla[NFTA_CHAIN_POLICY]);
- if (err < 0)
- return err;
- }
+ if (nla[NFTA_CHAIN_POLICY])
+ nft_base_chain(chain)->policy = policy;
if (nla[NFTA_CHAIN_COUNTERS]) {
if (!(chain->flags & NFT_BASE_CHAIN))
@@ -958,17 +952,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
}
chain->flags |= NFT_BASE_CHAIN;
-
- if (nla[NFTA_CHAIN_POLICY]) {
- err = nf_tables_chain_policy(basechain,
- nla[NFTA_CHAIN_POLICY]);
- if (err < 0) {
- free_percpu(basechain->stats);
- kfree(basechain);
- return err;
- }
- } else
- basechain->policy = NF_ACCEPT;
+ basechain->policy = policy;
if (nla[NFTA_CHAIN_COUNTERS]) {
err = nf_tables_counters(basechain,
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 12/23] netfilter: nf_tables: restore chain change atomicity
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
` (10 preceding siblings ...)
2014-01-10 0:35 ` [PATCH 11/23] netfilter: nf_tables: split chain policy validation from actually setting it Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 13/23] netfilter: nf_tables: fix check for table overflow Pablo Neira Ayuso
` (11 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Chain counter validation is performed after the chain policy has
potentially been changed. Move counter validation/setting before
changing of the chain policy to fix this.
Additionally fix a memory leak if chain counter allocation fails
for new chains, remove an unnecessary free_percpu() and move
counter allocation for new chains
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_tables_api.c | 43 ++++++++++++++++++++---------------------
1 file changed, 21 insertions(+), 22 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 30fad4f..d275d38 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -880,9 +880,6 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
!IS_ERR(nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME])))
return -EEXIST;
- if (nla[NFTA_CHAIN_POLICY])
- nft_base_chain(chain)->policy = policy;
-
if (nla[NFTA_CHAIN_COUNTERS]) {
if (!(chain->flags & NFT_BASE_CHAIN))
return -EOPNOTSUPP;
@@ -893,6 +890,9 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
return err;
}
+ if (nla[NFTA_CHAIN_POLICY])
+ nft_base_chain(chain)->policy = policy;
+
if (nla[NFTA_CHAIN_HANDLE] && name)
nla_strlcpy(chain->name, name, NFT_CHAIN_MAXNAMELEN);
@@ -934,6 +934,24 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
if (basechain == NULL)
return -ENOMEM;
+ if (nla[NFTA_CHAIN_COUNTERS]) {
+ err = nf_tables_counters(basechain,
+ nla[NFTA_CHAIN_COUNTERS]);
+ if (err < 0) {
+ kfree(basechain);
+ return err;
+ }
+ } else {
+ struct nft_stats __percpu *newstats;
+
+ newstats = alloc_percpu(struct nft_stats);
+ if (newstats == NULL) {
+ kfree(basechain);
+ return -ENOMEM;
+ }
+ rcu_assign_pointer(basechain->stats, newstats);
+ }
+
basechain->type = type;
chain = &basechain->chain;
@@ -953,25 +971,6 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
chain->flags |= NFT_BASE_CHAIN;
basechain->policy = policy;
-
- if (nla[NFTA_CHAIN_COUNTERS]) {
- err = nf_tables_counters(basechain,
- nla[NFTA_CHAIN_COUNTERS]);
- if (err < 0) {
- free_percpu(basechain->stats);
- kfree(basechain);
- return err;
- }
- } else {
- struct nft_stats __percpu *newstats;
-
- newstats = alloc_percpu(struct nft_stats);
- if (newstats == NULL)
- return -ENOMEM;
-
- rcu_assign_pointer(nft_base_chain(chain)->stats,
- newstats);
- }
} else {
chain = kzalloc(sizeof(*chain), GFP_KERNEL);
if (chain == NULL)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 13/23] netfilter: nf_tables: fix check for table overflow
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
` (11 preceding siblings ...)
2014-01-10 0:35 ` [PATCH 12/23] netfilter: nf_tables: restore chain change atomicity Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 14/23] netfilter: nf_tables: fix chain type module reference handling Pablo Neira Ayuso
` (10 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
The table use counter is only increased for new chains, so move the check
to the correct position.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_tables_api.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index d275d38..290472c 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -834,9 +834,6 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
if (IS_ERR(table))
return PTR_ERR(table);
- if (table->use == UINT_MAX)
- return -EOVERFLOW;
-
chain = NULL;
name = nla[NFTA_CHAIN_NAME];
@@ -899,6 +896,9 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
goto notify;
}
+ if (table->use == UINT_MAX)
+ return -EOVERFLOW;
+
if (nla[NFTA_CHAIN_HOOK]) {
struct nf_hook_ops *ops;
nf_hookfn *hookfn;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 14/23] netfilter: nf_tables: fix chain type module reference handling
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
` (12 preceding siblings ...)
2014-01-10 0:35 ` [PATCH 13/23] netfilter: nf_tables: fix check for table overflow Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 15/23] netfilter: nf_tables: add missing module references to chain types Pablo Neira Ayuso
` (9 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
The chain type module reference handling makes no sense at all: we take
a reference immediately when the module is registered, preventing the
module from ever being unloaded.
Fix by taking a reference when we're actually creating a chain of the
chain type and release the reference when destroying the chain.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 2 +-
net/netfilter/nf_tables_api.c | 45 ++++++++++++++++++++-----------------
2 files changed, 25 insertions(+), 22 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 5d2b703..e9b9786 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -436,7 +436,7 @@ struct nft_stats {
*/
struct nft_base_chain {
struct nf_hook_ops ops[NFT_HOOK_OPS_MAX];
- enum nft_chain_type type;
+ struct nf_chain_type *type;
u8 policy;
struct nft_stats __percpu *stats;
struct nft_chain chain;
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 290472c..d913fb0 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -126,27 +126,29 @@ static inline u64 nf_tables_alloc_handle(struct nft_table *table)
static struct nf_chain_type *chain_type[AF_MAX][NFT_CHAIN_T_MAX];
-static int __nf_tables_chain_type_lookup(int family, const struct nlattr *nla)
+static struct nf_chain_type *
+__nf_tables_chain_type_lookup(int family, const struct nlattr *nla)
{
int i;
- for (i=0; i<NFT_CHAIN_T_MAX; i++) {
+ for (i = 0; i < NFT_CHAIN_T_MAX; i++) {
if (chain_type[family][i] != NULL &&
!nla_strcmp(nla, chain_type[family][i]->name))
- return i;
+ return chain_type[family][i];
}
- return -1;
+ return NULL;
}
-static int nf_tables_chain_type_lookup(const struct nft_af_info *afi,
- const struct nlattr *nla,
- bool autoload)
+static struct nf_chain_type *
+nf_tables_chain_type_lookup(const struct nft_af_info *afi,
+ const struct nlattr *nla,
+ bool autoload)
{
- int type;
+ struct nf_chain_type *type;
type = __nf_tables_chain_type_lookup(afi->family, nla);
#ifdef CONFIG_MODULES
- if (type < 0 && autoload) {
+ if (type == NULL && autoload) {
nfnl_unlock(NFNL_SUBSYS_NFTABLES);
request_module("nft-chain-%u-%*.s", afi->family,
nla_len(nla)-1, (const char *)nla_data(nla));
@@ -478,10 +480,6 @@ int nft_register_chain_type(struct nf_chain_type *ctype)
err = -EBUSY;
goto out;
}
-
- if (!try_module_get(ctype->me))
- goto out;
-
chain_type[ctype->family][ctype->type] = ctype;
out:
nfnl_unlock(NFNL_SUBSYS_NFTABLES);
@@ -493,7 +491,6 @@ void nft_unregister_chain_type(struct nf_chain_type *ctype)
{
nfnl_lock(NFNL_SUBSYS_NFTABLES);
chain_type[ctype->family][ctype->type] = NULL;
- module_put(ctype->me);
nfnl_unlock(NFNL_SUBSYS_NFTABLES);
}
EXPORT_SYMBOL_GPL(nft_unregister_chain_type);
@@ -617,9 +614,8 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, u32 portid, u32 seq,
htonl(basechain->policy)))
goto nla_put_failure;
- if (nla_put_string(skb, NFTA_CHAIN_TYPE,
- chain_type[ops->pf][nft_base_chain(chain)->type]->name))
- goto nla_put_failure;
+ if (nla_put_string(skb, NFTA_CHAIN_TYPE, basechain->type->name))
+ goto nla_put_failure;
if (nft_dump_stats(skb, nft_base_chain(chain)->stats))
goto nla_put_failure;
@@ -900,16 +896,17 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
return -EOVERFLOW;
if (nla[NFTA_CHAIN_HOOK]) {
+ struct nf_chain_type *type;
struct nf_hook_ops *ops;
nf_hookfn *hookfn;
u32 hooknum, priority;
- int type = NFT_CHAIN_T_DEFAULT;
+ type = chain_type[family][NFT_CHAIN_T_DEFAULT];
if (nla[NFTA_CHAIN_TYPE]) {
type = nf_tables_chain_type_lookup(afi,
nla[NFTA_CHAIN_TYPE],
create);
- if (type < 0)
+ if (type == NULL)
return -ENOENT;
}
@@ -926,9 +923,11 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
return -EINVAL;
priority = ntohl(nla_get_be32(ha[NFTA_HOOK_PRIORITY]));
- if (!(chain_type[family][type]->hook_mask & (1 << hooknum)))
+ if (!(type->hook_mask & (1 << hooknum)))
return -EOPNOTSUPP;
- hookfn = chain_type[family][type]->fn[hooknum];
+ if (!try_module_get(type->me))
+ return -ENOENT;
+ hookfn = type->fn[hooknum];
basechain = kzalloc(sizeof(*basechain), GFP_KERNEL);
if (basechain == NULL)
@@ -938,6 +937,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
err = nf_tables_counters(basechain,
nla[NFTA_CHAIN_COUNTERS]);
if (err < 0) {
+ module_put(type->me);
kfree(basechain);
return err;
}
@@ -946,6 +946,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
newstats = alloc_percpu(struct nft_stats);
if (newstats == NULL) {
+ module_put(type->me);
kfree(basechain);
return -ENOMEM;
}
@@ -987,6 +988,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
chain->flags & NFT_BASE_CHAIN) {
err = nf_register_hooks(nft_base_chain(chain)->ops, afi->nops);
if (err < 0) {
+ module_put(basechain->type->me);
free_percpu(basechain->stats);
kfree(basechain);
return err;
@@ -1007,6 +1009,7 @@ static void nf_tables_rcu_chain_destroy(struct rcu_head *head)
BUG_ON(chain->use > 0);
if (chain->flags & NFT_BASE_CHAIN) {
+ module_put(nft_base_chain(chain)->type->me);
free_percpu(nft_base_chain(chain)->stats);
kfree(nft_base_chain(chain));
} else
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 15/23] netfilter: nf_tables: add missing module references to chain types
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
` (13 preceding siblings ...)
2014-01-10 0:35 ` [PATCH 14/23] netfilter: nf_tables: fix chain type module reference handling Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 16/23] netfilter: nf_tables: replay request after dropping locks to load chain type Pablo Neira Ayuso
` (8 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
In some cases we neither take a reference to the AF info nor to the
chain type, allowing the module to be unloaded while in use.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/bridge/netfilter/nf_tables_bridge.c | 1 +
net/ipv4/netfilter/nf_tables_arp.c | 1 +
net/ipv4/netfilter/nf_tables_ipv4.c | 1 +
net/ipv6/netfilter/nf_tables_ipv6.c | 1 +
net/netfilter/nf_tables_inet.c | 1 +
5 files changed, 5 insertions(+)
diff --git a/net/bridge/netfilter/nf_tables_bridge.c b/net/bridge/netfilter/nf_tables_bridge.c
index 003c1e9..f97222e 100644
--- a/net/bridge/netfilter/nf_tables_bridge.c
+++ b/net/bridge/netfilter/nf_tables_bridge.c
@@ -72,6 +72,7 @@ static struct nf_chain_type filter_bridge = {
.family = NFPROTO_BRIDGE,
.name = "filter",
.type = NFT_CHAIN_T_DEFAULT,
+ .me = THIS_MODULE,
.hook_mask = (1 << NF_BR_LOCAL_IN) |
(1 << NF_BR_FORWARD) |
(1 << NF_BR_LOCAL_OUT),
diff --git a/net/ipv4/netfilter/nf_tables_arp.c b/net/ipv4/netfilter/nf_tables_arp.c
index 36d27fc..228df00 100644
--- a/net/ipv4/netfilter/nf_tables_arp.c
+++ b/net/ipv4/netfilter/nf_tables_arp.c
@@ -72,6 +72,7 @@ static struct nf_chain_type filter_arp = {
.family = NFPROTO_ARP,
.name = "filter",
.type = NFT_CHAIN_T_DEFAULT,
+ .me = THIS_MODULE,
.hook_mask = (1 << NF_ARP_IN) |
(1 << NF_ARP_OUT) |
(1 << NF_ARP_FORWARD),
diff --git a/net/ipv4/netfilter/nf_tables_ipv4.c b/net/ipv4/netfilter/nf_tables_ipv4.c
index da927dc..d6fc1b4 100644
--- a/net/ipv4/netfilter/nf_tables_ipv4.c
+++ b/net/ipv4/netfilter/nf_tables_ipv4.c
@@ -95,6 +95,7 @@ static struct nf_chain_type filter_ipv4 = {
.family = NFPROTO_IPV4,
.name = "filter",
.type = NFT_CHAIN_T_DEFAULT,
+ .me = THIS_MODULE,
.hook_mask = (1 << NF_INET_LOCAL_IN) |
(1 << NF_INET_LOCAL_OUT) |
(1 << NF_INET_FORWARD) |
diff --git a/net/ipv6/netfilter/nf_tables_ipv6.c b/net/ipv6/netfilter/nf_tables_ipv6.c
index 025e7f4..a340276 100644
--- a/net/ipv6/netfilter/nf_tables_ipv6.c
+++ b/net/ipv6/netfilter/nf_tables_ipv6.c
@@ -94,6 +94,7 @@ static struct nf_chain_type filter_ipv6 = {
.family = NFPROTO_IPV6,
.name = "filter",
.type = NFT_CHAIN_T_DEFAULT,
+ .me = THIS_MODULE,
.hook_mask = (1 << NF_INET_LOCAL_IN) |
(1 << NF_INET_LOCAL_OUT) |
(1 << NF_INET_FORWARD) |
diff --git a/net/netfilter/nf_tables_inet.c b/net/netfilter/nf_tables_inet.c
index ac0edcb..280d3a2 100644
--- a/net/netfilter/nf_tables_inet.c
+++ b/net/netfilter/nf_tables_inet.c
@@ -70,6 +70,7 @@ static struct nf_chain_type filter_inet = {
.family = NFPROTO_INET,
.name = "filter",
.type = NFT_CHAIN_T_DEFAULT,
+ .me = THIS_MODULE,
.hook_mask = (1 << NF_INET_LOCAL_IN) |
(1 << NF_INET_LOCAL_OUT) |
(1 << NF_INET_FORWARD) |
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 16/23] netfilter: nf_tables: replay request after dropping locks to load chain type
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
` (14 preceding siblings ...)
2014-01-10 0:35 ` [PATCH 15/23] netfilter: nf_tables: add missing module references to chain types Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 17/23] netfilter: nf_tables: constify chain type definitions and pointers Pablo Neira Ayuso
` (7 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
To avoid races, we need to replay to request after dropping the nfnl_mutex
to auto-load the chain type module.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_tables_api.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index d913fb0..7d6a226 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -147,16 +147,20 @@ nf_tables_chain_type_lookup(const struct nft_af_info *afi,
struct nf_chain_type *type;
type = __nf_tables_chain_type_lookup(afi->family, nla);
+ if (type != NULL)
+ return type;
#ifdef CONFIG_MODULES
- if (type == NULL && autoload) {
+ if (autoload) {
nfnl_unlock(NFNL_SUBSYS_NFTABLES);
request_module("nft-chain-%u-%*.s", afi->family,
nla_len(nla)-1, (const char *)nla_data(nla));
nfnl_lock(NFNL_SUBSYS_NFTABLES);
type = __nf_tables_chain_type_lookup(afi->family, nla);
+ if (type != NULL)
+ return ERR_PTR(-EAGAIN);
}
#endif
- return type;
+ return ERR_PTR(-ENOENT);
}
static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = {
@@ -906,8 +910,8 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
type = nf_tables_chain_type_lookup(afi,
nla[NFTA_CHAIN_TYPE],
create);
- if (type == NULL)
- return -ENOENT;
+ if (IS_ERR(type))
+ return PTR_ERR(type);
}
err = nla_parse_nested(ha, NFTA_HOOK_MAX, nla[NFTA_CHAIN_HOOK],
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 17/23] netfilter: nf_tables: constify chain type definitions and pointers
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
` (15 preceding siblings ...)
2014-01-10 0:35 ` [PATCH 16/23] netfilter: nf_tables: replay request after dropping locks to load chain type Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 18/23] netfilter: nf_tables: minor nf_chain_type cleanups Pablo Neira Ayuso
` (6 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 6 +++---
net/bridge/netfilter/nf_tables_bridge.c | 2 +-
net/ipv4/netfilter/nf_tables_arp.c | 2 +-
net/ipv4/netfilter/nf_tables_ipv4.c | 2 +-
net/ipv4/netfilter/nft_chain_nat_ipv4.c | 2 +-
net/ipv4/netfilter/nft_chain_route_ipv4.c | 2 +-
net/ipv6/netfilter/nf_tables_ipv6.c | 2 +-
net/ipv6/netfilter/nft_chain_nat_ipv6.c | 2 +-
net/ipv6/netfilter/nft_chain_route_ipv6.c | 2 +-
net/netfilter/nf_tables_api.c | 14 +++++++-------
net/netfilter/nf_tables_inet.c | 2 +-
11 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index e9b9786..d3f7053 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -436,7 +436,7 @@ struct nft_stats {
*/
struct nft_base_chain {
struct nf_hook_ops ops[NFT_HOOK_OPS_MAX];
- struct nf_chain_type *type;
+ const struct nf_chain_type *type;
u8 policy;
struct nft_stats __percpu *stats;
struct nft_chain chain;
@@ -507,8 +507,8 @@ struct nf_chain_type {
int family;
};
-int nft_register_chain_type(struct nf_chain_type *);
-void nft_unregister_chain_type(struct nf_chain_type *);
+int nft_register_chain_type(const struct nf_chain_type *);
+void nft_unregister_chain_type(const struct nf_chain_type *);
int nft_register_expr(struct nft_expr_type *);
void nft_unregister_expr(struct nft_expr_type *);
diff --git a/net/bridge/netfilter/nf_tables_bridge.c b/net/bridge/netfilter/nf_tables_bridge.c
index f97222e..283658d 100644
--- a/net/bridge/netfilter/nf_tables_bridge.c
+++ b/net/bridge/netfilter/nf_tables_bridge.c
@@ -68,7 +68,7 @@ static struct pernet_operations nf_tables_bridge_net_ops = {
.exit = nf_tables_bridge_exit_net,
};
-static struct nf_chain_type filter_bridge = {
+static const struct nf_chain_type filter_bridge = {
.family = NFPROTO_BRIDGE,
.name = "filter",
.type = NFT_CHAIN_T_DEFAULT,
diff --git a/net/ipv4/netfilter/nf_tables_arp.c b/net/ipv4/netfilter/nf_tables_arp.c
index 228df00..8af01a5 100644
--- a/net/ipv4/netfilter/nf_tables_arp.c
+++ b/net/ipv4/netfilter/nf_tables_arp.c
@@ -68,7 +68,7 @@ static struct pernet_operations nf_tables_arp_net_ops = {
.exit = nf_tables_arp_exit_net,
};
-static struct nf_chain_type filter_arp = {
+static const struct nf_chain_type filter_arp = {
.family = NFPROTO_ARP,
.name = "filter",
.type = NFT_CHAIN_T_DEFAULT,
diff --git a/net/ipv4/netfilter/nf_tables_ipv4.c b/net/ipv4/netfilter/nf_tables_ipv4.c
index d6fc1b4..cec7805 100644
--- a/net/ipv4/netfilter/nf_tables_ipv4.c
+++ b/net/ipv4/netfilter/nf_tables_ipv4.c
@@ -91,7 +91,7 @@ static struct pernet_operations nf_tables_ipv4_net_ops = {
.exit = nf_tables_ipv4_exit_net,
};
-static struct nf_chain_type filter_ipv4 = {
+static const struct nf_chain_type filter_ipv4 = {
.family = NFPROTO_IPV4,
.name = "filter",
.type = NFT_CHAIN_T_DEFAULT,
diff --git a/net/ipv4/netfilter/nft_chain_nat_ipv4.c b/net/ipv4/netfilter/nft_chain_nat_ipv4.c
index cf2c792..9e535c2 100644
--- a/net/ipv4/netfilter/nft_chain_nat_ipv4.c
+++ b/net/ipv4/netfilter/nft_chain_nat_ipv4.c
@@ -164,7 +164,7 @@ static unsigned int nf_nat_output(const struct nf_hook_ops *ops,
return ret;
}
-static struct nf_chain_type nft_chain_nat_ipv4 = {
+static const struct nf_chain_type nft_chain_nat_ipv4 = {
.family = NFPROTO_IPV4,
.name = "nat",
.type = NFT_CHAIN_T_NAT,
diff --git a/net/ipv4/netfilter/nft_chain_route_ipv4.c b/net/ipv4/netfilter/nft_chain_route_ipv4.c
index 4e6bf9a..2dd2eea 100644
--- a/net/ipv4/netfilter/nft_chain_route_ipv4.c
+++ b/net/ipv4/netfilter/nft_chain_route_ipv4.c
@@ -61,7 +61,7 @@ static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops,
return ret;
}
-static struct nf_chain_type nft_chain_route_ipv4 = {
+static const struct nf_chain_type nft_chain_route_ipv4 = {
.family = NFPROTO_IPV4,
.name = "route",
.type = NFT_CHAIN_T_ROUTE,
diff --git a/net/ipv6/netfilter/nf_tables_ipv6.c b/net/ipv6/netfilter/nf_tables_ipv6.c
index a340276..758a32b 100644
--- a/net/ipv6/netfilter/nf_tables_ipv6.c
+++ b/net/ipv6/netfilter/nf_tables_ipv6.c
@@ -90,7 +90,7 @@ static struct pernet_operations nf_tables_ipv6_net_ops = {
.exit = nf_tables_ipv6_exit_net,
};
-static struct nf_chain_type filter_ipv6 = {
+static const struct nf_chain_type filter_ipv6 = {
.family = NFPROTO_IPV6,
.name = "filter",
.type = NFT_CHAIN_T_DEFAULT,
diff --git a/net/ipv6/netfilter/nft_chain_nat_ipv6.c b/net/ipv6/netfilter/nft_chain_nat_ipv6.c
index e86dcd7..efd1d57 100644
--- a/net/ipv6/netfilter/nft_chain_nat_ipv6.c
+++ b/net/ipv6/netfilter/nft_chain_nat_ipv6.c
@@ -170,7 +170,7 @@ static unsigned int nf_nat_ipv6_output(const struct nf_hook_ops *ops,
return ret;
}
-static struct nf_chain_type nft_chain_nat_ipv6 = {
+static const struct nf_chain_type nft_chain_nat_ipv6 = {
.family = NFPROTO_IPV6,
.name = "nat",
.type = NFT_CHAIN_T_NAT,
diff --git a/net/ipv6/netfilter/nft_chain_route_ipv6.c b/net/ipv6/netfilter/nft_chain_route_ipv6.c
index 3fe40f0..3620f88 100644
--- a/net/ipv6/netfilter/nft_chain_route_ipv6.c
+++ b/net/ipv6/netfilter/nft_chain_route_ipv6.c
@@ -59,7 +59,7 @@ static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops,
return ret;
}
-static struct nf_chain_type nft_chain_route_ipv6 = {
+static const struct nf_chain_type nft_chain_route_ipv6 = {
.family = NFPROTO_IPV6,
.name = "route",
.type = NFT_CHAIN_T_ROUTE,
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 7d6a226..acdd9d6 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -124,9 +124,9 @@ static inline u64 nf_tables_alloc_handle(struct nft_table *table)
return ++table->hgenerator;
}
-static struct nf_chain_type *chain_type[AF_MAX][NFT_CHAIN_T_MAX];
+static const struct nf_chain_type *chain_type[AF_MAX][NFT_CHAIN_T_MAX];
-static struct nf_chain_type *
+static const struct nf_chain_type *
__nf_tables_chain_type_lookup(int family, const struct nlattr *nla)
{
int i;
@@ -139,12 +139,12 @@ __nf_tables_chain_type_lookup(int family, const struct nlattr *nla)
return NULL;
}
-static struct nf_chain_type *
+static const struct nf_chain_type *
nf_tables_chain_type_lookup(const struct nft_af_info *afi,
const struct nlattr *nla,
bool autoload)
{
- struct nf_chain_type *type;
+ const struct nf_chain_type *type;
type = __nf_tables_chain_type_lookup(afi->family, nla);
if (type != NULL)
@@ -475,7 +475,7 @@ static int nf_tables_deltable(struct sock *nlsk, struct sk_buff *skb,
return 0;
}
-int nft_register_chain_type(struct nf_chain_type *ctype)
+int nft_register_chain_type(const struct nf_chain_type *ctype)
{
int err = 0;
@@ -491,7 +491,7 @@ out:
}
EXPORT_SYMBOL_GPL(nft_register_chain_type);
-void nft_unregister_chain_type(struct nf_chain_type *ctype)
+void nft_unregister_chain_type(const struct nf_chain_type *ctype)
{
nfnl_lock(NFNL_SUBSYS_NFTABLES);
chain_type[ctype->family][ctype->type] = NULL;
@@ -900,7 +900,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
return -EOVERFLOW;
if (nla[NFTA_CHAIN_HOOK]) {
- struct nf_chain_type *type;
+ const struct nf_chain_type *type;
struct nf_hook_ops *ops;
nf_hookfn *hookfn;
u32 hooknum, priority;
diff --git a/net/netfilter/nf_tables_inet.c b/net/netfilter/nf_tables_inet.c
index 280d3a2..ee29ba2 100644
--- a/net/netfilter/nf_tables_inet.c
+++ b/net/netfilter/nf_tables_inet.c
@@ -66,7 +66,7 @@ static struct pernet_operations nf_tables_inet_net_ops = {
.exit = nf_tables_inet_exit_net,
};
-static struct nf_chain_type filter_inet = {
+static const struct nf_chain_type filter_inet = {
.family = NFPROTO_INET,
.name = "filter",
.type = NFT_CHAIN_T_DEFAULT,
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 18/23] netfilter: nf_tables: minor nf_chain_type cleanups
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
` (16 preceding siblings ...)
2014-01-10 0:35 ` [PATCH 17/23] netfilter: nf_tables: constify chain type definitions and pointers Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 19/23] netfilter: nf_tables: perform flags validation before table allocation Pablo Neira Ayuso
` (5 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Minor nf_chain_type cleanups:
- reorder struct to plug a hoe
- rename struct module member to "owner" for consistency
- rename nf_hookfn array to "hooks" for consistency
- reorder initializers for better readability
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 22 ++++++++++++++++------
net/bridge/netfilter/nf_tables_bridge.c | 4 ++--
net/ipv4/netfilter/nf_tables_arp.c | 4 ++--
net/ipv4/netfilter/nf_tables_ipv4.c | 4 ++--
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 | 4 ++--
net/ipv6/netfilter/nft_chain_nat_ipv6.c | 6 +++---
net/ipv6/netfilter/nft_chain_route_ipv6.c | 6 +++---
net/netfilter/nf_tables_api.c | 12 ++++++------
net/netfilter/nf_tables_inet.c | 4 ++--
11 files changed, 44 insertions(+), 34 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index d3f7053..3422365 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -498,13 +498,23 @@ struct nft_af_info {
int nft_register_afinfo(struct net *, struct nft_af_info *);
void nft_unregister_afinfo(struct nft_af_info *);
+/**
+ * struct nf_chain_type - nf_tables chain type info
+ *
+ * @name: name of the type
+ * @type: numeric identifier
+ * @family: address family
+ * @owner: module owner
+ * @hook_mask: mask of valid hooks
+ * @hooks: hookfn overrides
+ */
struct nf_chain_type {
- unsigned int hook_mask;
- const char *name;
- enum nft_chain_type type;
- nf_hookfn *fn[NF_MAX_HOOKS];
- struct module *me;
- int family;
+ const char *name;
+ enum nft_chain_type type;
+ int family;
+ struct module *owner;
+ unsigned int hook_mask;
+ nf_hookfn *hooks[NF_MAX_HOOKS];
};
int nft_register_chain_type(const struct nf_chain_type *);
diff --git a/net/bridge/netfilter/nf_tables_bridge.c b/net/bridge/netfilter/nf_tables_bridge.c
index 283658d..c83fab5 100644
--- a/net/bridge/netfilter/nf_tables_bridge.c
+++ b/net/bridge/netfilter/nf_tables_bridge.c
@@ -69,10 +69,10 @@ static struct pernet_operations nf_tables_bridge_net_ops = {
};
static const struct nf_chain_type filter_bridge = {
- .family = NFPROTO_BRIDGE,
.name = "filter",
.type = NFT_CHAIN_T_DEFAULT,
- .me = THIS_MODULE,
+ .family = NFPROTO_BRIDGE,
+ .owner = THIS_MODULE,
.hook_mask = (1 << NF_BR_LOCAL_IN) |
(1 << NF_BR_FORWARD) |
(1 << NF_BR_LOCAL_OUT),
diff --git a/net/ipv4/netfilter/nf_tables_arp.c b/net/ipv4/netfilter/nf_tables_arp.c
index 8af01a5..b90d16c 100644
--- a/net/ipv4/netfilter/nf_tables_arp.c
+++ b/net/ipv4/netfilter/nf_tables_arp.c
@@ -69,10 +69,10 @@ static struct pernet_operations nf_tables_arp_net_ops = {
};
static const struct nf_chain_type filter_arp = {
- .family = NFPROTO_ARP,
.name = "filter",
.type = NFT_CHAIN_T_DEFAULT,
- .me = THIS_MODULE,
+ .family = NFPROTO_ARP,
+ .owner = THIS_MODULE,
.hook_mask = (1 << NF_ARP_IN) |
(1 << NF_ARP_OUT) |
(1 << NF_ARP_FORWARD),
diff --git a/net/ipv4/netfilter/nf_tables_ipv4.c b/net/ipv4/netfilter/nf_tables_ipv4.c
index cec7805..66679fd 100644
--- a/net/ipv4/netfilter/nf_tables_ipv4.c
+++ b/net/ipv4/netfilter/nf_tables_ipv4.c
@@ -92,10 +92,10 @@ static struct pernet_operations nf_tables_ipv4_net_ops = {
};
static const struct nf_chain_type filter_ipv4 = {
- .family = NFPROTO_IPV4,
.name = "filter",
.type = NFT_CHAIN_T_DEFAULT,
- .me = THIS_MODULE,
+ .family = NFPROTO_IPV4,
+ .owner = THIS_MODULE,
.hook_mask = (1 << NF_INET_LOCAL_IN) |
(1 << NF_INET_LOCAL_OUT) |
(1 << NF_INET_FORWARD) |
diff --git a/net/ipv4/netfilter/nft_chain_nat_ipv4.c b/net/ipv4/netfilter/nft_chain_nat_ipv4.c
index 9e535c2..208d60a 100644
--- a/net/ipv4/netfilter/nft_chain_nat_ipv4.c
+++ b/net/ipv4/netfilter/nft_chain_nat_ipv4.c
@@ -165,20 +165,20 @@ static unsigned int nf_nat_output(const struct nf_hook_ops *ops,
}
static const struct nf_chain_type nft_chain_nat_ipv4 = {
- .family = NFPROTO_IPV4,
.name = "nat",
.type = NFT_CHAIN_T_NAT,
+ .family = NFPROTO_IPV4,
+ .owner = THIS_MODULE,
.hook_mask = (1 << NF_INET_PRE_ROUTING) |
(1 << NF_INET_POST_ROUTING) |
(1 << NF_INET_LOCAL_OUT) |
(1 << NF_INET_LOCAL_IN),
- .fn = {
+ .hooks = {
[NF_INET_PRE_ROUTING] = nf_nat_prerouting,
[NF_INET_POST_ROUTING] = nf_nat_postrouting,
[NF_INET_LOCAL_OUT] = nf_nat_output,
[NF_INET_LOCAL_IN] = nf_nat_fn,
},
- .me = THIS_MODULE,
};
static int __init nft_chain_nat_init(void)
diff --git a/net/ipv4/netfilter/nft_chain_route_ipv4.c b/net/ipv4/netfilter/nft_chain_route_ipv4.c
index 2dd2eea..67db1bb 100644
--- a/net/ipv4/netfilter/nft_chain_route_ipv4.c
+++ b/net/ipv4/netfilter/nft_chain_route_ipv4.c
@@ -62,14 +62,14 @@ static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops,
}
static const struct nf_chain_type nft_chain_route_ipv4 = {
- .family = NFPROTO_IPV4,
.name = "route",
.type = NFT_CHAIN_T_ROUTE,
+ .family = NFPROTO_IPV4,
+ .owner = THIS_MODULE,
.hook_mask = (1 << NF_INET_LOCAL_OUT),
- .fn = {
+ .hooks = {
[NF_INET_LOCAL_OUT] = nf_route_table_hook,
},
- .me = THIS_MODULE,
};
static int __init nft_chain_route_init(void)
diff --git a/net/ipv6/netfilter/nf_tables_ipv6.c b/net/ipv6/netfilter/nf_tables_ipv6.c
index 758a32b..859fca0 100644
--- a/net/ipv6/netfilter/nf_tables_ipv6.c
+++ b/net/ipv6/netfilter/nf_tables_ipv6.c
@@ -91,10 +91,10 @@ static struct pernet_operations nf_tables_ipv6_net_ops = {
};
static const struct nf_chain_type filter_ipv6 = {
- .family = NFPROTO_IPV6,
.name = "filter",
.type = NFT_CHAIN_T_DEFAULT,
- .me = THIS_MODULE,
+ .family = NFPROTO_IPV6,
+ .owner = THIS_MODULE,
.hook_mask = (1 << NF_INET_LOCAL_IN) |
(1 << NF_INET_LOCAL_OUT) |
(1 << NF_INET_FORWARD) |
diff --git a/net/ipv6/netfilter/nft_chain_nat_ipv6.c b/net/ipv6/netfilter/nft_chain_nat_ipv6.c
index efd1d57..9ed60ab 100644
--- a/net/ipv6/netfilter/nft_chain_nat_ipv6.c
+++ b/net/ipv6/netfilter/nft_chain_nat_ipv6.c
@@ -171,20 +171,20 @@ static unsigned int nf_nat_ipv6_output(const struct nf_hook_ops *ops,
}
static const struct nf_chain_type nft_chain_nat_ipv6 = {
- .family = NFPROTO_IPV6,
.name = "nat",
.type = NFT_CHAIN_T_NAT,
+ .family = NFPROTO_IPV6,
+ .owner = THIS_MODULE,
.hook_mask = (1 << NF_INET_PRE_ROUTING) |
(1 << NF_INET_POST_ROUTING) |
(1 << NF_INET_LOCAL_OUT) |
(1 << NF_INET_LOCAL_IN),
- .fn = {
+ .hooks = {
[NF_INET_PRE_ROUTING] = nf_nat_ipv6_prerouting,
[NF_INET_POST_ROUTING] = nf_nat_ipv6_postrouting,
[NF_INET_LOCAL_OUT] = nf_nat_ipv6_output,
[NF_INET_LOCAL_IN] = nf_nat_ipv6_fn,
},
- .me = THIS_MODULE,
};
static int __init nft_chain_nat_ipv6_init(void)
diff --git a/net/ipv6/netfilter/nft_chain_route_ipv6.c b/net/ipv6/netfilter/nft_chain_route_ipv6.c
index 3620f88..b2b7eff 100644
--- a/net/ipv6/netfilter/nft_chain_route_ipv6.c
+++ b/net/ipv6/netfilter/nft_chain_route_ipv6.c
@@ -60,14 +60,14 @@ static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops,
}
static const struct nf_chain_type nft_chain_route_ipv6 = {
- .family = NFPROTO_IPV6,
.name = "route",
.type = NFT_CHAIN_T_ROUTE,
+ .family = NFPROTO_IPV6,
+ .owner = THIS_MODULE,
.hook_mask = (1 << NF_INET_LOCAL_OUT),
- .fn = {
+ .hooks = {
[NF_INET_LOCAL_OUT] = nf_route_table_hook,
},
- .me = THIS_MODULE,
};
static int __init nft_chain_route_init(void)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index acdd9d6..c8ca3b8 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -929,9 +929,9 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
if (!(type->hook_mask & (1 << hooknum)))
return -EOPNOTSUPP;
- if (!try_module_get(type->me))
+ if (!try_module_get(type->owner))
return -ENOENT;
- hookfn = type->fn[hooknum];
+ hookfn = type->hooks[hooknum];
basechain = kzalloc(sizeof(*basechain), GFP_KERNEL);
if (basechain == NULL)
@@ -941,7 +941,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
err = nf_tables_counters(basechain,
nla[NFTA_CHAIN_COUNTERS]);
if (err < 0) {
- module_put(type->me);
+ module_put(type->owner);
kfree(basechain);
return err;
}
@@ -950,7 +950,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
newstats = alloc_percpu(struct nft_stats);
if (newstats == NULL) {
- module_put(type->me);
+ module_put(type->owner);
kfree(basechain);
return -ENOMEM;
}
@@ -992,7 +992,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
chain->flags & NFT_BASE_CHAIN) {
err = nf_register_hooks(nft_base_chain(chain)->ops, afi->nops);
if (err < 0) {
- module_put(basechain->type->me);
+ module_put(basechain->type->owner);
free_percpu(basechain->stats);
kfree(basechain);
return err;
@@ -1013,7 +1013,7 @@ static void nf_tables_rcu_chain_destroy(struct rcu_head *head)
BUG_ON(chain->use > 0);
if (chain->flags & NFT_BASE_CHAIN) {
- module_put(nft_base_chain(chain)->type->me);
+ module_put(nft_base_chain(chain)->type->owner);
free_percpu(nft_base_chain(chain)->stats);
kfree(nft_base_chain(chain));
} else
diff --git a/net/netfilter/nf_tables_inet.c b/net/netfilter/nf_tables_inet.c
index ee29ba2..84478de 100644
--- a/net/netfilter/nf_tables_inet.c
+++ b/net/netfilter/nf_tables_inet.c
@@ -67,10 +67,10 @@ static struct pernet_operations nf_tables_inet_net_ops = {
};
static const struct nf_chain_type filter_inet = {
- .family = NFPROTO_INET,
.name = "filter",
.type = NFT_CHAIN_T_DEFAULT,
- .me = THIS_MODULE,
+ .family = NFPROTO_INET,
+ .owner = THIS_MODULE,
.hook_mask = (1 << NF_INET_LOCAL_IN) |
(1 << NF_INET_LOCAL_OUT) |
(1 << NF_INET_FORWARD) |
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 19/23] netfilter: nf_tables: perform flags validation before table allocation
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
` (17 preceding siblings ...)
2014-01-10 0:35 ` [PATCH 18/23] netfilter: nf_tables: minor nf_chain_type cleanups Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 20/23] netfilter: nf_tables: take AF module reference when creating a table Pablo Neira Ayuso
` (4 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
Simplifies error handling. Additionally use the correct type u32 for the
host byte order flags value.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_tables_api.c | 22 +++++++++-------------
1 file changed, 9 insertions(+), 13 deletions(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index c8ca3b8..88f9c94 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -366,7 +366,7 @@ static int nf_tables_updtable(struct sock *nlsk, struct sk_buff *skb,
int family = nfmsg->nfgen_family, ret = 0;
if (nla[NFTA_TABLE_FLAGS]) {
- __be32 flags;
+ u32 flags;
flags = ntohl(nla_get_be32(nla[NFTA_TABLE_FLAGS]));
if (flags & ~NFT_TABLE_F_DORMANT)
@@ -402,6 +402,7 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
struct nft_table *table;
struct net *net = sock_net(skb->sk);
int family = nfmsg->nfgen_family;
+ u32 flags = 0;
afi = nf_tables_afinfo_lookup(net, family, true);
if (IS_ERR(afi))
@@ -423,6 +424,12 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
return nf_tables_updtable(nlsk, skb, nlh, nla, afi, table);
}
+ if (nla[NFTA_TABLE_FLAGS]) {
+ flags = ntohl(nla_get_be32(nla[NFTA_TABLE_FLAGS]));
+ if (flags & ~NFT_TABLE_F_DORMANT)
+ return -EINVAL;
+ }
+
table = kzalloc(sizeof(*table) + nla_len(name), GFP_KERNEL);
if (table == NULL)
return -ENOMEM;
@@ -430,18 +437,7 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
nla_strlcpy(table->name, name, nla_len(name));
INIT_LIST_HEAD(&table->chains);
INIT_LIST_HEAD(&table->sets);
-
- if (nla[NFTA_TABLE_FLAGS]) {
- __be32 flags;
-
- flags = ntohl(nla_get_be32(nla[NFTA_TABLE_FLAGS]));
- if (flags & ~NFT_TABLE_F_DORMANT) {
- kfree(table);
- return -EINVAL;
- }
-
- table->flags |= flags;
- }
+ table->flags = flags;
list_add_tail(&table->list, &afi->tables);
nf_tables_table_notify(skb, nlh, table, NFT_MSG_NEWTABLE, family);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 20/23] netfilter: nf_tables: take AF module reference when creating a table
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
` (18 preceding siblings ...)
2014-01-10 0:35 ` [PATCH 19/23] netfilter: nf_tables: perform flags validation before table allocation Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 21/23] netfilter: nf_tables: prohibit deletion of a table with existing sets Pablo Neira Ayuso
` (3 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
The table refers to data of the AF module, so we need to make sure the
module isn't unloaded while the table exists.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_tables_api.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 88f9c94..c352614 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -430,9 +430,14 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
return -EINVAL;
}
+ if (!try_module_get(afi->owner))
+ return -EAFNOSUPPORT;
+
table = kzalloc(sizeof(*table) + nla_len(name), GFP_KERNEL);
- if (table == NULL)
+ if (table == NULL) {
+ module_put(afi->owner);
return -ENOMEM;
+ }
nla_strlcpy(table->name, name, nla_len(name));
INIT_LIST_HEAD(&table->chains);
@@ -468,6 +473,7 @@ static int nf_tables_deltable(struct sock *nlsk, struct sk_buff *skb,
list_del(&table->list);
nf_tables_table_notify(skb, nlh, table, NFT_MSG_DELTABLE, family);
kfree(table);
+ module_put(afi->owner);
return 0;
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 21/23] netfilter: nf_tables: prohibit deletion of a table with existing sets
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
` (19 preceding siblings ...)
2014-01-10 0:35 ` [PATCH 20/23] netfilter: nf_tables: take AF module reference when creating a table Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 22/23] netfilter: nf_tables: rename nft_do_chain_pktinfo() to nft_do_chain() Pablo Neira Ayuso
` (2 subsequent siblings)
23 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
We currently leak the set memory when deleting a table that still has
sets in it. Return EBUSY when attempting to delete a table with sets.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_tables_api.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index c352614..36add31 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -467,7 +467,7 @@ static int nf_tables_deltable(struct sock *nlsk, struct sk_buff *skb,
if (IS_ERR(table))
return PTR_ERR(table);
- if (table->use)
+ if (!list_empty(&table->chains) || !list_empty(&table->sets))
return -EBUSY;
list_del(&table->list);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 22/23] netfilter: nf_tables: rename nft_do_chain_pktinfo() to nft_do_chain()
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
` (20 preceding siblings ...)
2014-01-10 0:35 ` [PATCH 21/23] netfilter: nf_tables: prohibit deletion of a table with existing sets Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 23/23] netfilter: nf_tables: fix error path in the init functions Pablo Neira Ayuso
2014-01-10 2:36 ` [PATCH 00/23] nf_tables updates for net-next David Miller
23 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
From: Patrick McHardy <kaber@trash.net>
We don't encode argument types into function names and since besides
nft_do_chain() there are only AF-specific versions, there is no risk
of confusion.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 4 ++--
net/bridge/netfilter/nf_tables_bridge.c | 2 +-
net/ipv4/netfilter/nf_tables_arp.c | 2 +-
net/ipv4/netfilter/nf_tables_ipv4.c | 2 +-
net/ipv4/netfilter/nft_chain_nat_ipv4.c | 2 +-
net/ipv4/netfilter/nft_chain_route_ipv4.c | 2 +-
net/ipv6/netfilter/nf_tables_ipv6.c | 2 +-
net/ipv6/netfilter/nft_chain_nat_ipv6.c | 2 +-
net/ipv6/netfilter/nft_chain_route_ipv6.c | 2 +-
net/netfilter/nf_tables_core.c | 4 ++--
10 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 3422365..57c8ff7 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -447,8 +447,8 @@ static inline struct nft_base_chain *nft_base_chain(const struct nft_chain *chai
return container_of(chain, struct nft_base_chain, chain);
}
-unsigned int nft_do_chain_pktinfo(struct nft_pktinfo *pkt,
- const struct nf_hook_ops *ops);
+unsigned int nft_do_chain(struct nft_pktinfo *pkt,
+ const struct nf_hook_ops *ops);
/**
* struct nft_table - nf_tables table
diff --git a/net/bridge/netfilter/nf_tables_bridge.c b/net/bridge/netfilter/nf_tables_bridge.c
index c83fab5..5bcc0d8 100644
--- a/net/bridge/netfilter/nf_tables_bridge.c
+++ b/net/bridge/netfilter/nf_tables_bridge.c
@@ -25,7 +25,7 @@ nft_do_chain_bridge(const struct nf_hook_ops *ops,
nft_set_pktinfo(&pkt, ops, skb, in, out);
- return nft_do_chain_pktinfo(&pkt, ops);
+ return nft_do_chain(&pkt, ops);
}
static struct nft_af_info nft_af_bridge __read_mostly = {
diff --git a/net/ipv4/netfilter/nf_tables_arp.c b/net/ipv4/netfilter/nf_tables_arp.c
index b90d16c..19412a4 100644
--- a/net/ipv4/netfilter/nf_tables_arp.c
+++ b/net/ipv4/netfilter/nf_tables_arp.c
@@ -25,7 +25,7 @@ nft_do_chain_arp(const struct nf_hook_ops *ops,
nft_set_pktinfo(&pkt, ops, skb, in, out);
- return nft_do_chain_pktinfo(&pkt, ops);
+ return nft_do_chain(&pkt, ops);
}
static struct nft_af_info nft_af_arp __read_mostly = {
diff --git a/net/ipv4/netfilter/nf_tables_ipv4.c b/net/ipv4/netfilter/nf_tables_ipv4.c
index 66679fd..fec163a 100644
--- a/net/ipv4/netfilter/nf_tables_ipv4.c
+++ b/net/ipv4/netfilter/nf_tables_ipv4.c
@@ -28,7 +28,7 @@ static unsigned int nft_do_chain_ipv4(const struct nf_hook_ops *ops,
nft_set_pktinfo_ipv4(&pkt, ops, skb, in, out);
- return nft_do_chain_pktinfo(&pkt, ops);
+ return nft_do_chain(&pkt, ops);
}
static unsigned int nft_ipv4_output(const struct nf_hook_ops *ops,
diff --git a/net/ipv4/netfilter/nft_chain_nat_ipv4.c b/net/ipv4/netfilter/nft_chain_nat_ipv4.c
index 208d60a..b5b256d 100644
--- a/net/ipv4/netfilter/nft_chain_nat_ipv4.c
+++ b/net/ipv4/netfilter/nft_chain_nat_ipv4.c
@@ -75,7 +75,7 @@ static unsigned int nf_nat_fn(const struct nf_hook_ops *ops,
nft_set_pktinfo_ipv4(&pkt, ops, skb, in, out);
- ret = nft_do_chain_pktinfo(&pkt, ops);
+ ret = nft_do_chain(&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 67db1bb..125b667 100644
--- a/net/ipv4/netfilter/nft_chain_route_ipv4.c
+++ b/net/ipv4/netfilter/nft_chain_route_ipv4.c
@@ -47,7 +47,7 @@ static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops,
daddr = iph->daddr;
tos = iph->tos;
- ret = nft_do_chain_pktinfo(&pkt, ops);
+ ret = nft_do_chain(&pkt, ops);
if (ret != NF_DROP && ret != NF_QUEUE) {
iph = ip_hdr(skb);
diff --git a/net/ipv6/netfilter/nf_tables_ipv6.c b/net/ipv6/netfilter/nf_tables_ipv6.c
index 859fca0..59a43b4 100644
--- a/net/ipv6/netfilter/nf_tables_ipv6.c
+++ b/net/ipv6/netfilter/nf_tables_ipv6.c
@@ -28,7 +28,7 @@ static unsigned int nft_do_chain_ipv6(const struct nf_hook_ops *ops,
if (nft_set_pktinfo_ipv6(&pkt, ops, skb, in, out) < 0)
return NF_DROP;
- return nft_do_chain_pktinfo(&pkt, ops);
+ return nft_do_chain(&pkt, ops);
}
static unsigned int nft_ipv6_output(const struct nf_hook_ops *ops,
diff --git a/net/ipv6/netfilter/nft_chain_nat_ipv6.c b/net/ipv6/netfilter/nft_chain_nat_ipv6.c
index 9ed60ab..9c3297a 100644
--- a/net/ipv6/netfilter/nft_chain_nat_ipv6.c
+++ b/net/ipv6/netfilter/nft_chain_nat_ipv6.c
@@ -79,7 +79,7 @@ static unsigned int nf_nat_ipv6_fn(const struct nf_hook_ops *ops,
nft_set_pktinfo_ipv6(&pkt, ops, skb, in, out);
- ret = nft_do_chain_pktinfo(&pkt, ops);
+ ret = nft_do_chain(&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 b2b7eff..4203129 100644
--- a/net/ipv6/netfilter/nft_chain_route_ipv6.c
+++ b/net/ipv6/netfilter/nft_chain_route_ipv6.c
@@ -47,7 +47,7 @@ static unsigned int nf_route_table_hook(const struct nf_hook_ops *ops,
/* flowlabel and prio (includes version, which shouldn't change either */
flowlabel = *((u32 *)ipv6_hdr(skb));
- ret = nft_do_chain_pktinfo(&pkt, ops);
+ ret = nft_do_chain(&pkt, ops);
if (ret != NF_DROP && ret != NF_QUEUE &&
(memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) ||
memcmp(&ipv6_hdr(skb)->daddr, &daddr, sizeof(daddr)) ||
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c
index 5aae317..0d879fc 100644
--- a/net/netfilter/nf_tables_core.c
+++ b/net/netfilter/nf_tables_core.c
@@ -116,7 +116,7 @@ static inline void nft_trace_packet(const struct nft_pktinfo *pkt,
}
unsigned int
-nft_do_chain_pktinfo(struct nft_pktinfo *pkt, const struct nf_hook_ops *ops)
+nft_do_chain(struct nft_pktinfo *pkt, const struct nf_hook_ops *ops)
{
const struct nft_chain *chain = ops->priv;
const struct nft_rule *rule;
@@ -216,7 +216,7 @@ next_rule:
return nft_base_chain(chain)->policy;
}
-EXPORT_SYMBOL_GPL(nft_do_chain_pktinfo);
+EXPORT_SYMBOL_GPL(nft_do_chain);
int __init nf_tables_core_module_init(void)
{
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [PATCH 23/23] netfilter: nf_tables: fix error path in the init functions
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
` (21 preceding siblings ...)
2014-01-10 0:35 ` [PATCH 22/23] netfilter: nf_tables: rename nft_do_chain_pktinfo() to nft_do_chain() Pablo Neira Ayuso
@ 2014-01-10 0:35 ` Pablo Neira Ayuso
2014-01-10 2:36 ` [PATCH 00/23] nf_tables updates for net-next David Miller
23 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-10 0:35 UTC (permalink / raw)
To: netfilter-devel; +Cc: davem, netdev
We have to unregister chain type if this fails to register netns.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/ipv4/netfilter/nf_tables_ipv4.c | 8 +++++++-
net/ipv6/netfilter/nf_tables_ipv6.c | 8 +++++++-
net/netfilter/nf_tables_inet.c | 8 +++++++-
3 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/netfilter/nf_tables_ipv4.c b/net/ipv4/netfilter/nf_tables_ipv4.c
index fec163a..6820c8c 100644
--- a/net/ipv4/netfilter/nf_tables_ipv4.c
+++ b/net/ipv4/netfilter/nf_tables_ipv4.c
@@ -105,8 +105,14 @@ static const struct nf_chain_type filter_ipv4 = {
static int __init nf_tables_ipv4_init(void)
{
+ int ret;
+
nft_register_chain_type(&filter_ipv4);
- return register_pernet_subsys(&nf_tables_ipv4_net_ops);
+ ret = register_pernet_subsys(&nf_tables_ipv4_net_ops);
+ if (ret < 0)
+ nft_unregister_chain_type(&filter_ipv4);
+
+ return ret;
}
static void __exit nf_tables_ipv4_exit(void)
diff --git a/net/ipv6/netfilter/nf_tables_ipv6.c b/net/ipv6/netfilter/nf_tables_ipv6.c
index 59a43b4..0d812b3 100644
--- a/net/ipv6/netfilter/nf_tables_ipv6.c
+++ b/net/ipv6/netfilter/nf_tables_ipv6.c
@@ -104,8 +104,14 @@ static const struct nf_chain_type filter_ipv6 = {
static int __init nf_tables_ipv6_init(void)
{
+ int ret;
+
nft_register_chain_type(&filter_ipv6);
- return register_pernet_subsys(&nf_tables_ipv6_net_ops);
+ ret = register_pernet_subsys(&nf_tables_ipv6_net_ops);
+ if (ret < 0)
+ nft_unregister_chain_type(&filter_ipv6);
+
+ return ret;
}
static void __exit nf_tables_ipv6_exit(void)
diff --git a/net/netfilter/nf_tables_inet.c b/net/netfilter/nf_tables_inet.c
index 84478de..9dd2d21 100644
--- a/net/netfilter/nf_tables_inet.c
+++ b/net/netfilter/nf_tables_inet.c
@@ -80,8 +80,14 @@ static const struct nf_chain_type filter_inet = {
static int __init nf_tables_inet_init(void)
{
+ int ret;
+
nft_register_chain_type(&filter_inet);
- return register_pernet_subsys(&nf_tables_inet_net_ops);
+ ret = register_pernet_subsys(&nf_tables_inet_net_ops);
+ if (ret < 0)
+ nft_unregister_chain_type(&filter_inet);
+
+ return ret;
}
static void __exit nf_tables_inet_exit(void)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* Re: [PATCH 00/23] nf_tables updates for net-next
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
` (22 preceding siblings ...)
2014-01-10 0:35 ` [PATCH 23/23] netfilter: nf_tables: fix error path in the init functions Pablo Neira Ayuso
@ 2014-01-10 2:36 ` David Miller
23 siblings, 0 replies; 31+ messages in thread
From: David Miller @ 2014-01-10 2:36 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel, netdev
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Fri, 10 Jan 2014 01:35:19 +0100
> The following patchset contains the following nf_tables updates,
> mostly updates from Patrick McHardy, they are:
...
> git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nftables.git master
Pulled, thanks Pablo.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 01/23] netfilter: nft_reject: fix compilation warning if NF_TABLES_IPV6 is disabled
2014-01-10 20:33 ` Sergei Shtylyov
@ 2014-01-10 19:39 ` David Miller
0 siblings, 0 replies; 31+ messages in thread
From: David Miller @ 2014-01-10 19:39 UTC (permalink / raw)
To: sergei.shtylyov; +Cc: pablo, netfilter-devel, netdev
From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Date: Fri, 10 Jan 2014 23:33:22 +0300
> Hello.
>
> On 01/10/2014 03:35 AM, Pablo Neira Ayuso wrote:
>
>> net/netfilter/nft_reject.c: In function 'nft_reject_eval':
>> net/netfilter/nft_reject.c:37:14: warning: unused variable 'net'
>> [-Wunused-variable]
>
>> Reported-by: kbuild test robot <fengguang.wu@intel.com>
>> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
>> ---
>> net/netfilter/nft_reject.c | 3 ++-
>> 1 file changed, 2 insertions(+), 1 deletion(-)
>
>> diff --git a/net/netfilter/nft_reject.c b/net/netfilter/nft_reject.c
>> index 0d690d4..7ae63cd 100644
>> --- a/net/netfilter/nft_reject.c
>> +++ b/net/netfilter/nft_reject.c
>> @@ -34,8 +34,9 @@ static void nft_reject_eval(const struct nft_expr
>> *expr,
>> const struct nft_pktinfo *pkt)
>> {
>> struct nft_reject *priv = nft_expr_priv(expr);
>> +#if IS_ENABLED(CONFIG_NF_TABLES_IPV6)
>> struct net *net = dev_net((pkt->in != NULL) ? pkt->in : pkt->out);
>> -
>
> Why remove empty line after the declaration block?
Because "#endif" sort of serves the same purpose.
This is what I do too in this situation.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 08/23] netfilter: nft_ct: load both IPv4 and IPv6 conntrack modules for NFPROTO_INET
2014-01-10 20:40 ` Sergei Shtylyov
@ 2014-01-10 19:42 ` Patrick McHardy
2014-01-10 19:48 ` David Miller
0 siblings, 1 reply; 31+ messages in thread
From: Patrick McHardy @ 2014-01-10 19:42 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: Pablo Neira Ayuso, netfilter-devel, davem, netdev
On Fri, Jan 10, 2014 at 11:40:38PM +0300, Sergei Shtylyov wrote:
> On 01/10/2014 03:35 AM, Pablo Neira Ayuso wrote:
>
> >From: Patrick McHardy <kaber@trash.net>
>
> >The ct expression can currently not be used in the inet family since
> >we don't have a conntrack module for NFPROTO_INET, so
> >nf_ct_l3proto_try_module_get() fails. Add some manual handling to
> >load the modules for both NFPROTO_IPV4 and NFPROTO_IPV6 if the
> >ct expression is used in the inet family.
>
> >Signed-off-by: Patrick McHardy <kaber@trash.net>
> >Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> >---
> > net/netfilter/nft_ct.c | 39 ++++++++++++++++++++++++++++++++++++---
> > 1 file changed, 36 insertions(+), 3 deletions(-)
>
> >diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
> >index 955f4e6..3727a32 100644
> >--- a/net/netfilter/nft_ct.c
> >+++ b/net/netfilter/nft_ct.c
> [...]
> >+static void nft_ct_l3proto_module_put(uint8_t family)
> >+{
> >+ if (family == NFPROTO_INET) {
> >+ nf_ct_l3proto_module_put(NFPROTO_IPV4);
> >+ nf_ct_l3proto_module_put(NFPROTO_IPV6);
> >+ } else
> >+ nf_ct_l3proto_module_put(family);
>
> According to Documentation/CodingStyle, there should be {} in the
> *else* arm, as the other arm of *if* statement has it.
I can see you're looking out for the important stuff. I consistently
used this style in nftables so I'm not going to change it here.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 08/23] netfilter: nft_ct: load both IPv4 and IPv6 conntrack modules for NFPROTO_INET
2014-01-10 19:42 ` Patrick McHardy
@ 2014-01-10 19:48 ` David Miller
2014-01-10 19:59 ` Patrick McHardy
0 siblings, 1 reply; 31+ messages in thread
From: David Miller @ 2014-01-10 19:48 UTC (permalink / raw)
To: kaber; +Cc: sergei.shtylyov, pablo, netfilter-devel, netdev
From: Patrick McHardy <kaber@trash.net>
Date: Fri, 10 Jan 2014 19:42:36 +0000
> I can see you're looking out for the important stuff. I consistently
> used this style in nftables so I'm not going to change it here.
Patrick, please follow the coding style conventions of the kernel,
these issues are important for long term sanity of the kernel tree.
It helps people who are looking at the netfilter code who perhaps
do not do so usually. Do you really want to use a different style
and therefore make your code harder to read for them? Really?
Your code being consistent with your code only is less important than
all of the networking looking the same.
Thank you.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 08/23] netfilter: nft_ct: load both IPv4 and IPv6 conntrack modules for NFPROTO_INET
2014-01-10 19:48 ` David Miller
@ 2014-01-10 19:59 ` Patrick McHardy
0 siblings, 0 replies; 31+ messages in thread
From: Patrick McHardy @ 2014-01-10 19:59 UTC (permalink / raw)
To: David Miller; +Cc: sergei.shtylyov, pablo, netfilter-devel, netdev
On Fri, Jan 10, 2014 at 02:48:13PM -0500, David Miller wrote:
> From: Patrick McHardy <kaber@trash.net>
> Date: Fri, 10 Jan 2014 19:42:36 +0000
>
> > I can see you're looking out for the important stuff. I consistently
> > used this style in nftables so I'm not going to change it here.
>
> Patrick, please follow the coding style conventions of the kernel,
> these issues are important for long term sanity of the kernel tree.
>
> It helps people who are looking at the netfilter code who perhaps
> do not do so usually. Do you really want to use a different style
> and therefore make your code harder to read for them? Really?
>
> Your code being consistent with your code only is less important than
> all of the networking looking the same.
>
> Thank you.
I agree to this, in fact style divergences really bother me since they
divert my attention :) I considered consistency more important for minor
stuff like this, but I really don't mind to add extra braces.
But I guess we both agree that its not worth sending patches just to
change this but just fix this up next time that line is touched.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 01/23] netfilter: nft_reject: fix compilation warning if NF_TABLES_IPV6 is disabled
2014-01-10 0:35 ` [PATCH 01/23] netfilter: nft_reject: fix compilation warning if NF_TABLES_IPV6 is disabled Pablo Neira Ayuso
@ 2014-01-10 20:33 ` Sergei Shtylyov
2014-01-10 19:39 ` David Miller
0 siblings, 1 reply; 31+ messages in thread
From: Sergei Shtylyov @ 2014-01-10 20:33 UTC (permalink / raw)
To: Pablo Neira Ayuso, netfilter-devel; +Cc: davem, netdev
Hello.
On 01/10/2014 03:35 AM, Pablo Neira Ayuso wrote:
> net/netfilter/nft_reject.c: In function 'nft_reject_eval':
> net/netfilter/nft_reject.c:37:14: warning: unused variable 'net' [-Wunused-variable]
> Reported-by: kbuild test robot <fengguang.wu@intel.com>
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> ---
> net/netfilter/nft_reject.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
> diff --git a/net/netfilter/nft_reject.c b/net/netfilter/nft_reject.c
> index 0d690d4..7ae63cd 100644
> --- a/net/netfilter/nft_reject.c
> +++ b/net/netfilter/nft_reject.c
> @@ -34,8 +34,9 @@ static void nft_reject_eval(const struct nft_expr *expr,
> const struct nft_pktinfo *pkt)
> {
> struct nft_reject *priv = nft_expr_priv(expr);
> +#if IS_ENABLED(CONFIG_NF_TABLES_IPV6)
> struct net *net = dev_net((pkt->in != NULL) ? pkt->in : pkt->out);
> -
Why remove empty line after the declaration block?
> +#endif
> switch (priv->type) {
> case NFT_REJECT_ICMP_UNREACH:
> if (priv->family == NFPROTO_IPV4)
WBR, Sergei
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH 08/23] netfilter: nft_ct: load both IPv4 and IPv6 conntrack modules for NFPROTO_INET
2014-01-10 0:35 ` [PATCH 08/23] netfilter: nft_ct: load both IPv4 and IPv6 conntrack modules for NFPROTO_INET Pablo Neira Ayuso
@ 2014-01-10 20:40 ` Sergei Shtylyov
2014-01-10 19:42 ` Patrick McHardy
0 siblings, 1 reply; 31+ messages in thread
From: Sergei Shtylyov @ 2014-01-10 20:40 UTC (permalink / raw)
To: Pablo Neira Ayuso, netfilter-devel; +Cc: davem, netdev
On 01/10/2014 03:35 AM, Pablo Neira Ayuso wrote:
> From: Patrick McHardy <kaber@trash.net>
> The ct expression can currently not be used in the inet family since
> we don't have a conntrack module for NFPROTO_INET, so
> nf_ct_l3proto_try_module_get() fails. Add some manual handling to
> load the modules for both NFPROTO_IPV4 and NFPROTO_IPV6 if the
> ct expression is used in the inet family.
> Signed-off-by: Patrick McHardy <kaber@trash.net>
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> ---
> net/netfilter/nft_ct.c | 39 ++++++++++++++++++++++++++++++++++++---
> 1 file changed, 36 insertions(+), 3 deletions(-)
> diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
> index 955f4e6..3727a32 100644
> --- a/net/netfilter/nft_ct.c
> +++ b/net/netfilter/nft_ct.c
[...]
> +static void nft_ct_l3proto_module_put(uint8_t family)
> +{
> + if (family == NFPROTO_INET) {
> + nf_ct_l3proto_module_put(NFPROTO_IPV4);
> + nf_ct_l3proto_module_put(NFPROTO_IPV6);
> + } else
> + nf_ct_l3proto_module_put(family);
According to Documentation/CodingStyle, there should be {} in the *else*
arm, as the other arm of *if* statement has it.
> +}
> +
WBR, Sergei
^ permalink raw reply [flat|nested] 31+ messages in thread
end of thread, other threads:[~2014-01-10 19:59 UTC | newest]
Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-01-10 0:35 [PATCH 00/23] nf_tables updates for net-next Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 01/23] netfilter: nft_reject: fix compilation warning if NF_TABLES_IPV6 is disabled Pablo Neira Ayuso
2014-01-10 20:33 ` Sergei Shtylyov
2014-01-10 19:39 ` David Miller
2014-01-10 0:35 ` [PATCH 02/23] netfilter: nf_tables: make chain types override the default AF functions Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 03/23] netfilter: nf_tables: add hook ops to struct nft_pktinfo Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 04/23] netfilter: nf_tables: add support for multi family tables Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 05/23] netfilter: nf_tables: add "inet" table for IPv4/IPv6 Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 06/23] netfilter: nf_tables: add nfproto support to meta expression Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 07/23] netfilter: nft_meta: add l4proto support Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 08/23] netfilter: nft_ct: load both IPv4 and IPv6 conntrack modules for NFPROTO_INET Pablo Neira Ayuso
2014-01-10 20:40 ` Sergei Shtylyov
2014-01-10 19:42 ` Patrick McHardy
2014-01-10 19:48 ` David Miller
2014-01-10 19:59 ` Patrick McHardy
2014-01-10 0:35 ` [PATCH 09/23] netfilter: nft_ct: Add support to set the connmark Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 10/23] netfilter: nft_meta: fix lack of validation of the input register Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 11/23] netfilter: nf_tables: split chain policy validation from actually setting it Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 12/23] netfilter: nf_tables: restore chain change atomicity Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 13/23] netfilter: nf_tables: fix check for table overflow Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 14/23] netfilter: nf_tables: fix chain type module reference handling Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 15/23] netfilter: nf_tables: add missing module references to chain types Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 16/23] netfilter: nf_tables: replay request after dropping locks to load chain type Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 17/23] netfilter: nf_tables: constify chain type definitions and pointers Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 18/23] netfilter: nf_tables: minor nf_chain_type cleanups Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 19/23] netfilter: nf_tables: perform flags validation before table allocation Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 20/23] netfilter: nf_tables: take AF module reference when creating a table Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 21/23] netfilter: nf_tables: prohibit deletion of a table with existing sets Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 22/23] netfilter: nf_tables: rename nft_do_chain_pktinfo() to nft_do_chain() Pablo Neira Ayuso
2014-01-10 0:35 ` [PATCH 23/23] netfilter: nf_tables: fix error path in the init functions Pablo Neira Ayuso
2014-01-10 2:36 ` [PATCH 00/23] nf_tables updates for net-next David Miller
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).