From 3b088c4bc0035da662faa81818ba217e34c4bba4 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Fri, 3 Jan 2014 12:16:13 +0000 Subject: netfilter: nf_tables: make chain types override the default AF functions 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 Signed-off-by: Pablo Neira Ayuso --- net/ipv6/netfilter/nf_tables_ipv6.c | 48 ++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 28 deletions(-) (limited to 'net/ipv6') diff --git a/net/ipv6/netfilter/nf_tables_ipv6.c b/net/ipv6/netfilter/nf_tables_ipv6.c index d77db8a13505..54a2bcdc8a17 100644 --- a/net/ipv6/netfilter/nf_tables_ipv6.c +++ b/net/ipv6/netfilter/nf_tables_ipv6.c @@ -16,24 +16,35 @@ #include #include +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) -- cgit v1.2.3 From 115a60b173af0170e0db26b9a3fd6a911fba70a3 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Fri, 3 Jan 2014 12:16:15 +0000 Subject: netfilter: nf_tables: add support for multi family tables Add support to register chains to multiple hooks for different address families for mixed IPv4/IPv6 tables. Signed-off-by: Patrick McHardy --- 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(-) (limited to 'net/ipv6') diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index c9e63167f9a2..f066f252e5e5 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 c5fdd9a693be..003c1e9a8b0c 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 31bb778cebb8..36d27fc7e859 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 ed7e15a93410..177c3bceb7ca 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 54a2bcdc8a17..642280e44b65 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 d568626bc0f9..572d88dd3e5f 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 da0c1f4ada12..82cb8236f8a1 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) -- cgit v1.2.3 From 1d49144c0aaa61be4e3ccbef9cc5c40b0ec5f2fe Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Fri, 3 Jan 2014 12:16:16 +0000 Subject: netfilter: nf_tables: add "inet" table for IPv4/IPv6 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 Signed-off-by: Pablo Neira Ayuso --- 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 (limited to 'net/ipv6') diff --git a/include/net/netfilter/nf_tables_ipv4.h b/include/net/netfilter/nf_tables_ipv4.h index 1be1c2c197ee..f7b3a669aad3 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 4a9b88a65963..3d8ae489be0d 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 15d056d534e3..26a394cb91a8 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 f7dc0ebeeba5..ef1b1f88ca18 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 177c3bceb7ca..da927dc9f636 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 642280e44b65..025e7f4e8ac5 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 c3b3b26c4c4e..37d2092705a7 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 78b4e1c9c595..74c066109334 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 000000000000..ac0edcb549de --- /dev/null +++ b/net/netfilter/nf_tables_inet.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2012-2014 Patrick McHardy + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +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 "); +MODULE_ALIAS_NFT_FAMILY(1); -- cgit v1.2.3 From 88ce65a71c39901494eb2f1393856bff8ba0158d Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Thu, 9 Jan 2014 18:42:35 +0000 Subject: netfilter: nf_tables: add missing module references to chain types 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 Signed-off-by: Pablo Neira Ayuso --- 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(+) (limited to 'net/ipv6') diff --git a/net/bridge/netfilter/nf_tables_bridge.c b/net/bridge/netfilter/nf_tables_bridge.c index 003c1e9a8b0c..f97222eb8235 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 36d27fc7e859..228df003f3cc 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 da927dc9f636..d6fc1b4ace4e 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 025e7f4e8ac5..a34027687ecd 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 ac0edcb549de..280d3a2d5abc 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) | -- cgit v1.2.3 From 2a37d755b885995443f11cdcaf1f9d4b5f246eab Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Thu, 9 Jan 2014 18:42:37 +0000 Subject: netfilter: nf_tables: constify chain type definitions and pointers Signed-off-by: Patrick McHardy Signed-off-by: Pablo Neira Ayuso --- 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(-) (limited to 'net/ipv6') diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index e9b97862bf52..d3f70530a59a 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 f97222eb8235..283658d21825 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 228df003f3cc..8af01a5e8f98 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 d6fc1b4ace4e..cec7805de3e3 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 cf2c792cd971..9e535c2c2cd2 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 4e6bf9a3d7aa..2dd2eeaad15f 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 a34027687ecd..758a32b0e2ff 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 e86dcd70dc76..efd1d57a610a 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 3fe40f0456ad..3620f8851eba 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 7d6a2264ae0a..acdd9d68d52f 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 280d3a2d5abc..ee29ba2829d0 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, -- cgit v1.2.3 From fa2c1de0bbd98985f7f930205de97ae0d3e86c16 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Thu, 9 Jan 2014 18:42:38 +0000 Subject: netfilter: nf_tables: minor nf_chain_type cleanups 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 Signed-off-by: Pablo Neira Ayuso --- 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(-) (limited to 'net/ipv6') diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index d3f70530a59a..342236550ef9 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 283658d21825..c83fab5f8736 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 8af01a5e8f98..b90d16c332ab 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 cec7805de3e3..66679fd4b022 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 9e535c2c2cd2..208d60afaaa0 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 2dd2eeaad15f..67db1bbde1c8 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 758a32b0e2ff..859fca0432ff 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 efd1d57a610a..9ed60ab833f5 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 3620f8851eba..b2b7effa896b 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 acdd9d68d52f..c8ca3b8762b4 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 ee29ba2829d0..84478de179ea 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) | -- cgit v1.2.3 From 3876d22dba62ebf6582f33e1ef2160eeb95e1129 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Thu, 9 Jan 2014 18:42:43 +0000 Subject: netfilter: nf_tables: rename nft_do_chain_pktinfo() to nft_do_chain() 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 Signed-off-by: Pablo Neira Ayuso --- 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(-) (limited to 'net/ipv6') diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 342236550ef9..57c8ff7955df 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 c83fab5f8736..5bcc0d8b31f2 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 b90d16c332ab..19412a4063fb 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 66679fd4b022..fec163a6ac38 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 208d60afaaa0..b5b256d45e67 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 67db1bbde1c8..125b66766c0a 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 859fca0432ff..59a43b474dca 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 9ed60ab833f5..9c3297a768fd 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 b2b7effa896b..42031299585e 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 5aae31772ff7..0d879fcb8763 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) { -- cgit v1.2.3 From cf4dfa85395ebe2769267a072b39e48301669842 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 9 Jan 2014 20:32:19 +0100 Subject: netfilter: nf_tables: fix error path in the init functions We have to unregister chain type if this fails to register netns. Signed-off-by: Pablo Neira Ayuso --- 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(-) (limited to 'net/ipv6') diff --git a/net/ipv4/netfilter/nf_tables_ipv4.c b/net/ipv4/netfilter/nf_tables_ipv4.c index fec163a6ac38..6820c8c40842 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 59a43b474dca..0d812b31277d 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 84478de179ea..9dd2d216cfc1 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) -- cgit v1.2.3