1 From: Pablo Neira Ayuso <pablo@netfilter.org>
2 Date: Tue, 23 Mar 2021 00:56:28 +0100
3 Subject: [PATCH] netfilter: nftables: update table flags from the commit
6 Do not update table flags from the preparation phase. Store the flags
7 update into the transaction, then update the flags from the commit
10 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
13 --- a/include/net/netfilter/nf_tables.h
14 +++ b/include/net/netfilter/nf_tables.h
15 @@ -1470,13 +1470,16 @@ struct nft_trans_chain {
17 struct nft_trans_table {
24 #define nft_trans_table_update(trans) \
25 (((struct nft_trans_table *)trans->data)->update)
26 -#define nft_trans_table_enable(trans) \
27 - (((struct nft_trans_table *)trans->data)->enable)
28 +#define nft_trans_table_state(trans) \
29 + (((struct nft_trans_table *)trans->data)->state)
30 +#define nft_trans_table_flags(trans) \
31 + (((struct nft_trans_table *)trans->data)->flags)
33 struct nft_trans_elem {
35 --- a/net/netfilter/nf_tables_api.c
36 +++ b/net/netfilter/nf_tables_api.c
37 @@ -891,6 +891,12 @@ static void nf_tables_table_disable(stru
38 nft_table_disable(net, table, 0);
42 + NFT_TABLE_STATE_UNCHANGED = 0,
43 + NFT_TABLE_STATE_DORMANT,
44 + NFT_TABLE_STATE_WAKEUP
47 static int nf_tables_updtable(struct nft_ctx *ctx)
49 struct nft_trans *trans;
50 @@ -914,19 +920,17 @@ static int nf_tables_updtable(struct nft
52 if ((flags & NFT_TABLE_F_DORMANT) &&
53 !(ctx->table->flags & NFT_TABLE_F_DORMANT)) {
54 - nft_trans_table_enable(trans) = false;
55 + nft_trans_table_state(trans) = NFT_TABLE_STATE_DORMANT;
56 } else if (!(flags & NFT_TABLE_F_DORMANT) &&
57 ctx->table->flags & NFT_TABLE_F_DORMANT) {
58 - ctx->table->flags &= ~NFT_TABLE_F_DORMANT;
59 ret = nf_tables_table_enable(ctx->net, ctx->table);
61 - nft_trans_table_enable(trans) = true;
63 - ctx->table->flags |= NFT_TABLE_F_DORMANT;
64 + nft_trans_table_state(trans) = NFT_TABLE_STATE_WAKEUP;
69 + nft_trans_table_flags(trans) = flags;
70 nft_trans_table_update(trans) = true;
71 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
73 @@ -7918,11 +7922,10 @@ static int nf_tables_commit(struct net *
74 switch (trans->msg_type) {
75 case NFT_MSG_NEWTABLE:
76 if (nft_trans_table_update(trans)) {
77 - if (!nft_trans_table_enable(trans)) {
78 - nf_tables_table_disable(net,
80 - trans->ctx.table->flags |= NFT_TABLE_F_DORMANT;
82 + if (nft_trans_table_state(trans) == NFT_TABLE_STATE_DORMANT)
83 + nf_tables_table_disable(net, trans->ctx.table);
85 + trans->ctx.table->flags = nft_trans_table_flags(trans);
87 nft_clear(net, trans->ctx.table);
89 @@ -8135,11 +8138,9 @@ static int __nf_tables_abort(struct net
90 switch (trans->msg_type) {
91 case NFT_MSG_NEWTABLE:
92 if (nft_trans_table_update(trans)) {
93 - if (nft_trans_table_enable(trans)) {
94 - nf_tables_table_disable(net,
96 - trans->ctx.table->flags |= NFT_TABLE_F_DORMANT;
98 + if (nft_trans_table_state(trans) == NFT_TABLE_STATE_WAKEUP)
99 + nf_tables_table_disable(net, trans->ctx.table);
101 nft_trans_destroy(trans);
103 list_del_rcu(&trans->ctx.table->list);