Skip to content

Commit 0ce7cf4

Browse files
committed
netfilter: nftables: update table flags from the commit phase
Do not update table flags from the preparation phase. Store the flags update into the transaction, then update the flags from the commit phase. Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 1b9cd76 commit 0ce7cf4

File tree

2 files changed

+22
-18
lines changed

2 files changed

+22
-18
lines changed

include/net/netfilter/nf_tables.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,13 +1498,16 @@ struct nft_trans_chain {
14981498

14991499
struct nft_trans_table {
15001500
bool update;
1501-
bool enable;
1501+
u8 state;
1502+
u32 flags;
15021503
};
15031504

15041505
#define nft_trans_table_update(trans) \
15051506
(((struct nft_trans_table *)trans->data)->update)
1506-
#define nft_trans_table_enable(trans) \
1507-
(((struct nft_trans_table *)trans->data)->enable)
1507+
#define nft_trans_table_state(trans) \
1508+
(((struct nft_trans_table *)trans->data)->state)
1509+
#define nft_trans_table_flags(trans) \
1510+
(((struct nft_trans_table *)trans->data)->flags)
15081511

15091512
struct nft_trans_elem {
15101513
struct nft_set *set;

net/netfilter/nf_tables_api.c

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,12 @@ static void nf_tables_table_disable(struct net *net, struct nft_table *table)
900900
nft_table_disable(net, table, 0);
901901
}
902902

903+
enum {
904+
NFT_TABLE_STATE_UNCHANGED = 0,
905+
NFT_TABLE_STATE_DORMANT,
906+
NFT_TABLE_STATE_WAKEUP
907+
};
908+
903909
static int nf_tables_updtable(struct nft_ctx *ctx)
904910
{
905911
struct nft_trans *trans;
@@ -929,19 +935,17 @@ static int nf_tables_updtable(struct nft_ctx *ctx)
929935

930936
if ((flags & NFT_TABLE_F_DORMANT) &&
931937
!(ctx->table->flags & NFT_TABLE_F_DORMANT)) {
932-
nft_trans_table_enable(trans) = false;
938+
nft_trans_table_state(trans) = NFT_TABLE_STATE_DORMANT;
933939
} else if (!(flags & NFT_TABLE_F_DORMANT) &&
934940
ctx->table->flags & NFT_TABLE_F_DORMANT) {
935-
ctx->table->flags &= ~NFT_TABLE_F_DORMANT;
936941
ret = nf_tables_table_enable(ctx->net, ctx->table);
937942
if (ret >= 0)
938-
nft_trans_table_enable(trans) = true;
939-
else
940-
ctx->table->flags |= NFT_TABLE_F_DORMANT;
943+
nft_trans_table_state(trans) = NFT_TABLE_STATE_WAKEUP;
941944
}
942945
if (ret < 0)
943946
goto err;
944947

948+
nft_trans_table_flags(trans) = flags;
945949
nft_trans_table_update(trans) = true;
946950
list_add_tail(&trans->list, &ctx->net->nft.commit_list);
947951
return 0;
@@ -8068,11 +8072,10 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
80688072
switch (trans->msg_type) {
80698073
case NFT_MSG_NEWTABLE:
80708074
if (nft_trans_table_update(trans)) {
8071-
if (!nft_trans_table_enable(trans)) {
8072-
nf_tables_table_disable(net,
8073-
trans->ctx.table);
8074-
trans->ctx.table->flags |= NFT_TABLE_F_DORMANT;
8075-
}
8075+
if (nft_trans_table_state(trans) == NFT_TABLE_STATE_DORMANT)
8076+
nf_tables_table_disable(net, trans->ctx.table);
8077+
8078+
trans->ctx.table->flags = nft_trans_table_flags(trans);
80768079
} else {
80778080
nft_clear(net, trans->ctx.table);
80788081
}
@@ -8283,11 +8286,9 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
82838286
switch (trans->msg_type) {
82848287
case NFT_MSG_NEWTABLE:
82858288
if (nft_trans_table_update(trans)) {
8286-
if (nft_trans_table_enable(trans)) {
8287-
nf_tables_table_disable(net,
8288-
trans->ctx.table);
8289-
trans->ctx.table->flags |= NFT_TABLE_F_DORMANT;
8290-
}
8289+
if (nft_trans_table_state(trans) == NFT_TABLE_STATE_WAKEUP)
8290+
nf_tables_table_disable(net, trans->ctx.table);
8291+
82918292
nft_trans_destroy(trans);
82928293
} else {
82938294
list_del_rcu(&trans->ctx.table->list);

0 commit comments

Comments
 (0)