diff options
author | Felix Fietkau <nbd@nbd.name> | 2018-02-05 13:02:34 +0100 |
---|---|---|
committer | Felix Fietkau <nbd@nbd.name> | 2018-02-21 20:12:42 +0100 |
commit | b7265c59ab7dd0ec5dccb96e7b0dc1432404feb7 (patch) | |
tree | 8d777d4971194420cdfa245742e665996f0cf3b6 /target/linux/generic/backport-4.14/303-netfilter-nf_tables-remove-multihook-chains-and-fami.patch | |
parent | bc3e0f6052547fbffa9fcf1a6c7e340a95aa9f46 (diff) | |
download | upstream-b7265c59ab7dd0ec5dccb96e7b0dc1432404feb7.tar.gz upstream-b7265c59ab7dd0ec5dccb96e7b0dc1432404feb7.tar.bz2 upstream-b7265c59ab7dd0ec5dccb96e7b0dc1432404feb7.zip |
kernel: backport a series of netfilter cleanup patches to 4.14
Preparation for backporting upstream NAT offload support
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'target/linux/generic/backport-4.14/303-netfilter-nf_tables-remove-multihook-chains-and-fami.patch')
-rw-r--r-- | target/linux/generic/backport-4.14/303-netfilter-nf_tables-remove-multihook-chains-and-fami.patch | 391 |
1 files changed, 391 insertions, 0 deletions
diff --git a/target/linux/generic/backport-4.14/303-netfilter-nf_tables-remove-multihook-chains-and-fami.patch b/target/linux/generic/backport-4.14/303-netfilter-nf_tables-remove-multihook-chains-and-fami.patch new file mode 100644 index 0000000000..6395dd0795 --- /dev/null +++ b/target/linux/generic/backport-4.14/303-netfilter-nf_tables-remove-multihook-chains-and-fami.patch @@ -0,0 +1,391 @@ +From: Pablo Neira Ayuso <pablo@netfilter.org> +Date: Sat, 9 Dec 2017 15:40:25 +0100 +Subject: [PATCH] netfilter: nf_tables: remove multihook chains and families + +Since NFPROTO_INET is handled from the core, we don't need to maintain +extra infrastructure in nf_tables to handle the double hook +registration, one for IPv4 and another for IPv6. + +Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> +--- + +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -892,8 +892,6 @@ struct nft_stats { + struct u64_stats_sync syncp; + }; + +-#define NFT_HOOK_OPS_MAX 2 +- + /** + * struct nft_base_chain - nf_tables base chain + * +@@ -905,7 +903,7 @@ struct nft_stats { + * @dev_name: device name that this base chain is attached to (if any) + */ + struct nft_base_chain { +- struct nf_hook_ops ops[NFT_HOOK_OPS_MAX]; ++ struct nf_hook_ops ops; + const struct nf_chain_type *type; + u8 policy; + u8 flags; +@@ -966,8 +964,6 @@ enum nft_af_flags { + * @owner: module owner + * @tables: used internally + * @flags: family flags +- * @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 { +@@ -977,9 +973,6 @@ struct nft_af_info { + struct module *owner; + struct list_head tables; + u32 flags; +- unsigned int nops; +- void (*hook_ops_init)(struct nf_hook_ops *, +- unsigned int); + nf_hookfn *hooks[NF_MAX_HOOKS]; + }; + +--- a/net/bridge/netfilter/nf_tables_bridge.c ++++ b/net/bridge/netfilter/nf_tables_bridge.c +@@ -46,7 +46,6 @@ static struct nft_af_info nft_af_bridge + .family = NFPROTO_BRIDGE, + .nhooks = NF_BR_NUMHOOKS, + .owner = THIS_MODULE, +- .nops = 1, + .hooks = { + [NF_BR_PRE_ROUTING] = nft_do_chain_bridge, + [NF_BR_LOCAL_IN] = nft_do_chain_bridge, +--- a/net/ipv4/netfilter/nf_tables_arp.c ++++ b/net/ipv4/netfilter/nf_tables_arp.c +@@ -31,7 +31,6 @@ static struct nft_af_info nft_af_arp __r + .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, +--- a/net/ipv4/netfilter/nf_tables_ipv4.c ++++ b/net/ipv4/netfilter/nf_tables_ipv4.c +@@ -49,7 +49,6 @@ static struct nft_af_info nft_af_ipv4 __ + .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, +--- a/net/ipv6/netfilter/nf_tables_ipv6.c ++++ b/net/ipv6/netfilter/nf_tables_ipv6.c +@@ -46,7 +46,6 @@ static struct nft_af_info nft_af_ipv6 __ + .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, +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -139,29 +139,26 @@ static void nft_trans_destroy(struct nft + kfree(trans); + } + +-static int nf_tables_register_hooks(struct net *net, +- const struct nft_table *table, +- struct nft_chain *chain, +- unsigned int hook_nops) ++static int nf_tables_register_hook(struct net *net, ++ const struct nft_table *table, ++ struct nft_chain *chain) + { + if (table->flags & NFT_TABLE_F_DORMANT || + !nft_is_base_chain(chain)) + return 0; + +- return nf_register_net_hooks(net, nft_base_chain(chain)->ops, +- hook_nops); ++ return nf_register_net_hook(net, &nft_base_chain(chain)->ops); + } + +-static void nf_tables_unregister_hooks(struct net *net, +- const struct nft_table *table, +- struct nft_chain *chain, +- unsigned int hook_nops) ++static void nf_tables_unregister_hook(struct net *net, ++ const struct nft_table *table, ++ struct nft_chain *chain) + { + if (table->flags & NFT_TABLE_F_DORMANT || + !nft_is_base_chain(chain)) + return; + +- nf_unregister_net_hooks(net, nft_base_chain(chain)->ops, hook_nops); ++ nf_unregister_net_hook(net, &nft_base_chain(chain)->ops); + } + + static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type) +@@ -595,8 +592,7 @@ static void _nf_tables_table_disable(str + if (cnt && i++ == cnt) + break; + +- nf_unregister_net_hooks(net, nft_base_chain(chain)->ops, +- afi->nops); ++ nf_unregister_net_hook(net, &nft_base_chain(chain)->ops); + } + } + +@@ -613,8 +609,7 @@ static int nf_tables_table_enable(struct + if (!nft_is_base_chain(chain)) + continue; + +- err = nf_register_net_hooks(net, nft_base_chain(chain)->ops, +- afi->nops); ++ err = nf_register_net_hook(net, &nft_base_chain(chain)->ops); + if (err < 0) + goto err; + +@@ -1026,7 +1021,7 @@ static int nf_tables_fill_chain_info(str + + if (nft_is_base_chain(chain)) { + const struct nft_base_chain *basechain = nft_base_chain(chain); +- const struct nf_hook_ops *ops = &basechain->ops[0]; ++ const struct nf_hook_ops *ops = &basechain->ops; + struct nlattr *nest; + + nest = nla_nest_start(skb, NFTA_CHAIN_HOOK); +@@ -1252,8 +1247,8 @@ static void nf_tables_chain_destroy(stru + free_percpu(basechain->stats); + if (basechain->stats) + static_branch_dec(&nft_counters_enabled); +- if (basechain->ops[0].dev != NULL) +- dev_put(basechain->ops[0].dev); ++ if (basechain->ops.dev != NULL) ++ dev_put(basechain->ops.dev); + kfree(chain->name); + kfree(basechain); + } else { +@@ -1349,7 +1344,6 @@ static int nf_tables_addchain(struct nft + struct nft_stats __percpu *stats; + struct net *net = ctx->net; + struct nft_chain *chain; +- unsigned int i; + int err; + + if (table->use == UINT_MAX) +@@ -1388,21 +1382,18 @@ static int nf_tables_addchain(struct nft + basechain->type = hook.type; + chain = &basechain->chain; + +- for (i = 0; i < afi->nops; i++) { +- ops = &basechain->ops[i]; +- ops->pf = family; +- ops->hooknum = hook.num; +- ops->priority = hook.priority; +- ops->priv = chain; +- ops->hook = afi->hooks[ops->hooknum]; +- ops->dev = hook.dev; +- if (hookfn) +- ops->hook = hookfn; +- if (afi->hook_ops_init) +- afi->hook_ops_init(ops, i); +- if (basechain->type->type == NFT_CHAIN_T_NAT) +- ops->nat_hook = true; +- } ++ ops = &basechain->ops; ++ ops->pf = family; ++ ops->hooknum = hook.num; ++ ops->priority = hook.priority; ++ ops->priv = chain; ++ ops->hook = afi->hooks[ops->hooknum]; ++ ops->dev = hook.dev; ++ if (hookfn) ++ ops->hook = hookfn; ++ ++ if (basechain->type->type == NFT_CHAIN_T_NAT) ++ ops->nat_hook = true; + + chain->flags |= NFT_BASE_CHAIN; + basechain->policy = policy; +@@ -1420,7 +1411,7 @@ static int nf_tables_addchain(struct nft + goto err1; + } + +- err = nf_tables_register_hooks(net, table, chain, afi->nops); ++ err = nf_tables_register_hook(net, table, chain); + if (err < 0) + goto err1; + +@@ -1434,7 +1425,7 @@ static int nf_tables_addchain(struct nft + + return 0; + err2: +- nf_tables_unregister_hooks(net, table, chain, afi->nops); ++ nf_tables_unregister_hook(net, table, chain); + err1: + nf_tables_chain_destroy(chain); + +@@ -1447,14 +1438,13 @@ static int nf_tables_updchain(struct nft + const struct nlattr * const *nla = ctx->nla; + struct nft_table *table = ctx->table; + struct nft_chain *chain = ctx->chain; +- struct nft_af_info *afi = ctx->afi; + struct nft_base_chain *basechain; + struct nft_stats *stats = NULL; + struct nft_chain_hook hook; + const struct nlattr *name; + struct nf_hook_ops *ops; + struct nft_trans *trans; +- int err, i; ++ int err; + + if (nla[NFTA_CHAIN_HOOK]) { + if (!nft_is_base_chain(chain)) +@@ -1471,14 +1461,12 @@ static int nf_tables_updchain(struct nft + return -EBUSY; + } + +- for (i = 0; i < afi->nops; i++) { +- ops = &basechain->ops[i]; +- if (ops->hooknum != hook.num || +- ops->priority != hook.priority || +- ops->dev != hook.dev) { +- nft_chain_release_hook(&hook); +- return -EBUSY; +- } ++ ops = &basechain->ops; ++ if (ops->hooknum != hook.num || ++ ops->priority != hook.priority || ++ ops->dev != hook.dev) { ++ nft_chain_release_hook(&hook); ++ return -EBUSY; + } + nft_chain_release_hook(&hook); + } +@@ -5060,10 +5048,9 @@ static int nf_tables_commit(struct net * + case NFT_MSG_DELCHAIN: + list_del_rcu(&trans->ctx.chain->list); + nf_tables_chain_notify(&trans->ctx, NFT_MSG_DELCHAIN); +- nf_tables_unregister_hooks(trans->ctx.net, +- trans->ctx.table, +- trans->ctx.chain, +- trans->ctx.afi->nops); ++ nf_tables_unregister_hook(trans->ctx.net, ++ trans->ctx.table, ++ trans->ctx.chain); + break; + case NFT_MSG_NEWRULE: + nft_clear(trans->ctx.net, nft_trans_rule(trans)); +@@ -5200,10 +5187,9 @@ static int nf_tables_abort(struct net *n + } else { + trans->ctx.table->use--; + list_del_rcu(&trans->ctx.chain->list); +- nf_tables_unregister_hooks(trans->ctx.net, +- trans->ctx.table, +- trans->ctx.chain, +- trans->ctx.afi->nops); ++ nf_tables_unregister_hook(trans->ctx.net, ++ trans->ctx.table, ++ trans->ctx.chain); + } + break; + case NFT_MSG_DELCHAIN: +@@ -5304,7 +5290,7 @@ int nft_chain_validate_hooks(const struc + if (nft_is_base_chain(chain)) { + basechain = nft_base_chain(chain); + +- if ((1 << basechain->ops[0].hooknum) & hook_flags) ++ if ((1 << basechain->ops.hooknum) & hook_flags) + return 0; + + return -EOPNOTSUPP; +@@ -5786,8 +5772,7 @@ int __nft_release_basechain(struct nft_c + + BUG_ON(!nft_is_base_chain(ctx->chain)); + +- nf_tables_unregister_hooks(ctx->net, ctx->chain->table, ctx->chain, +- ctx->afi->nops); ++ nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain); + list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) { + list_del(&rule->list); + ctx->chain->use--; +@@ -5816,8 +5801,7 @@ static void __nft_release_afinfo(struct + + list_for_each_entry_safe(table, nt, &afi->tables, list) { + list_for_each_entry(chain, &table->chains, list) +- nf_tables_unregister_hooks(net, table, chain, +- afi->nops); ++ nf_tables_unregister_hook(net, table, chain); + /* No packets are walking on these chains anymore. */ + ctx.table = table; + list_for_each_entry(chain, &table->chains, list) { +--- a/net/netfilter/nf_tables_inet.c ++++ b/net/netfilter/nf_tables_inet.c +@@ -74,7 +74,6 @@ static struct nft_af_info nft_af_inet __ + .family = NFPROTO_INET, + .nhooks = NF_INET_NUMHOOKS, + .owner = THIS_MODULE, +- .nops = 1, + .hooks = { + [NF_INET_LOCAL_IN] = nft_do_chain_inet, + [NF_INET_LOCAL_OUT] = nft_inet_output, +--- a/net/netfilter/nf_tables_netdev.c ++++ b/net/netfilter/nf_tables_netdev.c +@@ -43,7 +43,6 @@ static struct nft_af_info nft_af_netdev + .nhooks = NF_NETDEV_NUMHOOKS, + .owner = THIS_MODULE, + .flags = NFT_AF_NEEDS_DEV, +- .nops = 1, + .hooks = { + [NF_NETDEV_INGRESS] = nft_do_chain_netdev, + }, +@@ -98,7 +97,7 @@ static void nft_netdev_event(unsigned lo + __nft_release_basechain(ctx); + break; + case NETDEV_CHANGENAME: +- if (dev->ifindex != basechain->ops[0].dev->ifindex) ++ if (dev->ifindex != basechain->ops.dev->ifindex) + return; + + strncpy(basechain->dev_name, dev->name, IFNAMSIZ); +--- a/net/netfilter/nft_compat.c ++++ b/net/netfilter/nft_compat.c +@@ -169,7 +169,7 @@ nft_target_set_tgchk_param(struct xt_tgc + if (nft_is_base_chain(ctx->chain)) { + const struct nft_base_chain *basechain = + nft_base_chain(ctx->chain); +- const struct nf_hook_ops *ops = &basechain->ops[0]; ++ const struct nf_hook_ops *ops = &basechain->ops; + + par->hook_mask = 1 << ops->hooknum; + } else { +@@ -302,7 +302,7 @@ static int nft_target_validate(const str + if (nft_is_base_chain(ctx->chain)) { + const struct nft_base_chain *basechain = + nft_base_chain(ctx->chain); +- const struct nf_hook_ops *ops = &basechain->ops[0]; ++ const struct nf_hook_ops *ops = &basechain->ops; + + hook_mask = 1 << ops->hooknum; + if (target->hooks && !(hook_mask & target->hooks)) +@@ -383,7 +383,7 @@ nft_match_set_mtchk_param(struct xt_mtch + if (nft_is_base_chain(ctx->chain)) { + const struct nft_base_chain *basechain = + nft_base_chain(ctx->chain); +- const struct nf_hook_ops *ops = &basechain->ops[0]; ++ const struct nf_hook_ops *ops = &basechain->ops; + + par->hook_mask = 1 << ops->hooknum; + } else { +@@ -481,7 +481,7 @@ static int nft_match_validate(const stru + if (nft_is_base_chain(ctx->chain)) { + const struct nft_base_chain *basechain = + nft_base_chain(ctx->chain); +- const struct nf_hook_ops *ops = &basechain->ops[0]; ++ const struct nf_hook_ops *ops = &basechain->ops; + + hook_mask = 1 << ops->hooknum; + if (match->hooks && !(hook_mask & match->hooks)) |