Skip to content

Commit a37061a

Browse files
Florian Westphalummakynes
authored andcommitted
netfilter: lift one-nat-hook-only restriction
This reverts commit f92b40a ("netfilter: core: only allow one nat hook per hook point"), this limitation is no longer needed. The nat core now invokes these functions and makes sure that hook evaluation stops after a mapping is created and a null binding is created otherwise. Signed-off-by: Florian Westphal <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 9971a51 commit a37061a

File tree

3 files changed

+2
-70
lines changed

3 files changed

+2
-70
lines changed

include/linux/netfilter.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ struct nf_hook_ops {
6767
struct net_device *dev;
6868
void *priv;
6969
u_int8_t pf;
70-
bool nat_hook;
7170
unsigned int hooknum;
7271
/* Hooks are ordered in ascending priority. */
7372
int priority;

net/netfilter/core.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,6 @@ nf_hook_entries_grow(const struct nf_hook_entries *old,
138138
continue;
139139
}
140140

141-
if (reg->nat_hook && orig_ops[i]->nat_hook) {
142-
kvfree(new);
143-
return ERR_PTR(-EBUSY);
144-
}
145-
146141
if (inserted || reg->priority > orig_ops[i]->priority) {
147142
new_ops[nhooks] = (void *)orig_ops[i];
148143
new->hooks[nhooks] = old->hooks[i];

net/netfilter/nf_tables_api.c

Lines changed: 2 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -74,64 +74,12 @@ static void nft_trans_destroy(struct nft_trans *trans)
7474
kfree(trans);
7575
}
7676

77-
/* removal requests are queued in the commit_list, but not acted upon
78-
* until after all new rules are in place.
79-
*
80-
* Therefore, nf_register_net_hook(net, &nat_hook) runs before pending
81-
* nf_unregister_net_hook().
82-
*
83-
* nf_register_net_hook thus fails if a nat hook is already in place
84-
* even if the conflicting hook is about to be removed.
85-
*
86-
* If collision is detected, search commit_log for DELCHAIN matching
87-
* the new nat hooknum; if we find one collision is temporary:
88-
*
89-
* Either transaction is aborted (new/colliding hook is removed), or
90-
* transaction is committed (old hook is removed).
91-
*/
92-
static bool nf_tables_allow_nat_conflict(const struct net *net,
93-
const struct nf_hook_ops *ops)
94-
{
95-
const struct nft_trans *trans;
96-
bool ret = false;
97-
98-
if (!ops->nat_hook)
99-
return false;
100-
101-
list_for_each_entry(trans, &net->nft.commit_list, list) {
102-
const struct nf_hook_ops *pending_ops;
103-
const struct nft_chain *pending;
104-
105-
if (trans->msg_type != NFT_MSG_NEWCHAIN &&
106-
trans->msg_type != NFT_MSG_DELCHAIN)
107-
continue;
108-
109-
pending = trans->ctx.chain;
110-
if (!nft_is_base_chain(pending))
111-
continue;
112-
113-
pending_ops = &nft_base_chain(pending)->ops;
114-
if (pending_ops->nat_hook &&
115-
pending_ops->pf == ops->pf &&
116-
pending_ops->hooknum == ops->hooknum) {
117-
/* other hook registration already pending? */
118-
if (trans->msg_type == NFT_MSG_NEWCHAIN)
119-
return false;
120-
121-
ret = true;
122-
}
123-
}
124-
125-
return ret;
126-
}
127-
12877
static int nf_tables_register_hook(struct net *net,
12978
const struct nft_table *table,
13079
struct nft_chain *chain)
13180
{
13281
const struct nft_base_chain *basechain;
133-
struct nf_hook_ops *ops;
134-
int ret;
82+
const struct nf_hook_ops *ops;
13583

13684
if (table->flags & NFT_TABLE_F_DORMANT ||
13785
!nft_is_base_chain(chain))
@@ -143,14 +91,7 @@ static int nf_tables_register_hook(struct net *net,
14391
if (basechain->type->ops_register)
14492
return basechain->type->ops_register(net, ops);
14593

146-
ret = nf_register_net_hook(net, ops);
147-
if (ret == -EBUSY && nf_tables_allow_nat_conflict(net, ops)) {
148-
ops->nat_hook = false;
149-
ret = nf_register_net_hook(net, ops);
150-
ops->nat_hook = true;
151-
}
152-
153-
return ret;
94+
return nf_register_net_hook(net, ops);
15495
}
15596

15697
static void nf_tables_unregister_hook(struct net *net,
@@ -1418,9 +1359,6 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
14181359
ops->hook = hook.type->hooks[ops->hooknum];
14191360
ops->dev = hook.dev;
14201361

1421-
if (basechain->type->type == NFT_CHAIN_T_NAT)
1422-
ops->nat_hook = true;
1423-
14241362
chain->flags |= NFT_BASE_CHAIN;
14251363
basechain->policy = policy;
14261364
} else {

0 commit comments

Comments
 (0)