Skip to content

Commit 4e25ceb

Browse files
Florian Westphalummakynes
authored andcommitted
netfilter: nf_tables: allow chain type to override hook register
Will be used in followup patch when nat types no longer use nf_register_net_hook() but will instead register with the nat core. Signed-off-by: Florian Westphal <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent ba7d284 commit 4e25ceb

File tree

4 files changed

+47
-23
lines changed

4 files changed

+47
-23
lines changed

include/net/netfilter/nf_tables.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -880,8 +880,8 @@ enum nft_chain_types {
880880
* @owner: module owner
881881
* @hook_mask: mask of valid hooks
882882
* @hooks: array of hook functions
883-
* @init: chain initialization function
884-
* @free: chain release function
883+
* @ops_register: base chain register function
884+
* @ops_unregister: base chain unregister function
885885
*/
886886
struct nft_chain_type {
887887
const char *name;
@@ -890,8 +890,8 @@ struct nft_chain_type {
890890
struct module *owner;
891891
unsigned int hook_mask;
892892
nf_hookfn *hooks[NF_MAX_HOOKS];
893-
int (*init)(struct nft_ctx *ctx);
894-
void (*free)(struct nft_ctx *ctx);
893+
int (*ops_register)(struct net *net, const struct nf_hook_ops *ops);
894+
void (*ops_unregister)(struct net *net, const struct nf_hook_ops *ops);
895895
};
896896

897897
int nft_chain_validate_dependency(const struct nft_chain *chain,

net/ipv4/netfilter/nft_chain_nat_ipv4.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,21 @@ static unsigned int nft_nat_ipv4_local_fn(void *priv,
6666
return nf_nat_ipv4_local_fn(priv, skb, state, nft_nat_do_chain);
6767
}
6868

69-
static int nft_nat_ipv4_init(struct nft_ctx *ctx)
69+
static int nft_nat_ipv4_reg(struct net *net, const struct nf_hook_ops *ops)
7070
{
71-
return nf_ct_netns_get(ctx->net, ctx->family);
71+
int ret = nf_register_net_hook(net, ops);
72+
if (ret == 0) {
73+
ret = nf_ct_netns_get(net, NFPROTO_IPV4);
74+
if (ret)
75+
nf_unregister_net_hook(net, ops);
76+
}
77+
return ret;
7278
}
7379

74-
static void nft_nat_ipv4_free(struct nft_ctx *ctx)
80+
static void nft_nat_ipv4_unreg(struct net *net, const struct nf_hook_ops *ops)
7581
{
76-
nf_ct_netns_put(ctx->net, ctx->family);
82+
nf_unregister_net_hook(net, ops);
83+
nf_ct_netns_put(net, NFPROTO_IPV4);
7784
}
7885

7986
static const struct nft_chain_type nft_chain_nat_ipv4 = {
@@ -91,8 +98,8 @@ static const struct nft_chain_type nft_chain_nat_ipv4 = {
9198
[NF_INET_LOCAL_OUT] = nft_nat_ipv4_local_fn,
9299
[NF_INET_LOCAL_IN] = nft_nat_ipv4_fn,
93100
},
94-
.init = nft_nat_ipv4_init,
95-
.free = nft_nat_ipv4_free,
101+
.ops_register = nft_nat_ipv4_reg,
102+
.ops_unregister = nft_nat_ipv4_unreg,
96103
};
97104

98105
static int __init nft_chain_nat_init(void)

net/ipv6/netfilter/nft_chain_nat_ipv6.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,22 @@ static unsigned int nft_nat_ipv6_local_fn(void *priv,
6464
return nf_nat_ipv6_local_fn(priv, skb, state, nft_nat_do_chain);
6565
}
6666

67-
static int nft_nat_ipv6_init(struct nft_ctx *ctx)
67+
static int nft_nat_ipv6_reg(struct net *net, const struct nf_hook_ops *ops)
6868
{
69-
return nf_ct_netns_get(ctx->net, ctx->family);
69+
int ret = nf_register_net_hook(net, ops);
70+
if (ret == 0) {
71+
ret = nf_ct_netns_get(net, NFPROTO_IPV6);
72+
if (ret)
73+
nf_unregister_net_hook(net, ops);
74+
}
75+
76+
return ret;
7077
}
7178

72-
static void nft_nat_ipv6_free(struct nft_ctx *ctx)
79+
static void nft_nat_ipv6_unreg(struct net *net, const struct nf_hook_ops *ops)
7380
{
74-
nf_ct_netns_put(ctx->net, ctx->family);
81+
nf_unregister_net_hook(net, ops);
82+
nf_ct_netns_put(net, NFPROTO_IPV6);
7583
}
7684

7785
static const struct nft_chain_type nft_chain_nat_ipv6 = {
@@ -89,8 +97,8 @@ static const struct nft_chain_type nft_chain_nat_ipv6 = {
8997
[NF_INET_LOCAL_OUT] = nft_nat_ipv6_local_fn,
9098
[NF_INET_LOCAL_IN] = nft_nat_ipv6_fn,
9199
},
92-
.init = nft_nat_ipv6_init,
93-
.free = nft_nat_ipv6_free,
100+
.ops_register = nft_nat_ipv6_reg,
101+
.ops_unregister = nft_nat_ipv6_unreg,
94102
};
95103

96104
static int __init nft_chain_nat_ipv6_init(void)

net/netfilter/nf_tables_api.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,20 @@ static int nf_tables_register_hook(struct net *net,
129129
const struct nft_table *table,
130130
struct nft_chain *chain)
131131
{
132+
const struct nft_base_chain *basechain;
132133
struct nf_hook_ops *ops;
133134
int ret;
134135

135136
if (table->flags & NFT_TABLE_F_DORMANT ||
136137
!nft_is_base_chain(chain))
137138
return 0;
138139

139-
ops = &nft_base_chain(chain)->ops;
140+
basechain = nft_base_chain(chain);
141+
ops = &basechain->ops;
142+
143+
if (basechain->type->ops_register)
144+
return basechain->type->ops_register(net, ops);
145+
140146
ret = nf_register_net_hook(net, ops);
141147
if (ret == -EBUSY && nf_tables_allow_nat_conflict(net, ops)) {
142148
ops->nat_hook = false;
@@ -151,11 +157,19 @@ static void nf_tables_unregister_hook(struct net *net,
151157
const struct nft_table *table,
152158
struct nft_chain *chain)
153159
{
160+
const struct nft_base_chain *basechain;
161+
const struct nf_hook_ops *ops;
162+
154163
if (table->flags & NFT_TABLE_F_DORMANT ||
155164
!nft_is_base_chain(chain))
156165
return;
166+
basechain = nft_base_chain(chain);
167+
ops = &basechain->ops;
168+
169+
if (basechain->type->ops_unregister)
170+
return basechain->type->ops_unregister(net, ops);
157171

158-
nf_unregister_net_hook(net, &nft_base_chain(chain)->ops);
172+
nf_unregister_net_hook(net, ops);
159173
}
160174

161175
static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type)
@@ -1262,8 +1276,6 @@ static void nf_tables_chain_destroy(struct nft_ctx *ctx)
12621276
if (nft_is_base_chain(chain)) {
12631277
struct nft_base_chain *basechain = nft_base_chain(chain);
12641278

1265-
if (basechain->type->free)
1266-
basechain->type->free(ctx);
12671279
module_put(basechain->type->owner);
12681280
free_percpu(basechain->stats);
12691281
if (basechain->stats)
@@ -1396,9 +1408,6 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
13961408
}
13971409

13981410
basechain->type = hook.type;
1399-
if (basechain->type->init)
1400-
basechain->type->init(ctx);
1401-
14021411
chain = &basechain->chain;
14031412

14041413
ops = &basechain->ops;

0 commit comments

Comments
 (0)