Skip to content

Commit b380e5c

Browse files
committed
netfilter: nf_tables: add message type to transactions
The patch adds message type to the transaction to simplify the commit the and abort routines. Yet another step forward in the generalisation of the transaction infrastructure. Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 37082f9 commit b380e5c

File tree

2 files changed

+45
-31
lines changed

2 files changed

+45
-31
lines changed

include/net/netfilter/nf_tables.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,11 +390,13 @@ struct nft_rule {
390390
* struct nft_trans - nf_tables object update in transaction
391391
*
392392
* @list: used internally
393+
* @msg_type: message type
393394
* @ctx: transaction context
394395
* @data: internal information related to the transaction
395396
*/
396397
struct nft_trans {
397398
struct list_head list;
399+
int msg_type;
398400
struct nft_ctx ctx;
399401
char data[0];
400402
};

net/netfilter/nf_tables_api.c

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,16 @@ static void nft_ctx_init(struct nft_ctx *ctx,
105105
ctx->nla = nla;
106106
}
107107

108-
static struct nft_trans *nft_trans_alloc(struct nft_ctx *ctx, u32 size)
108+
static struct nft_trans *nft_trans_alloc(struct nft_ctx *ctx, int msg_type,
109+
u32 size)
109110
{
110111
struct nft_trans *trans;
111112

112113
trans = kzalloc(sizeof(struct nft_trans) + size, GFP_KERNEL);
113114
if (trans == NULL)
114115
return NULL;
115116

117+
trans->msg_type = msg_type;
116118
trans->ctx = *ctx;
117119

118120
return trans;
@@ -1576,12 +1578,12 @@ static void nf_tables_rule_destroy(const struct nft_ctx *ctx,
15761578
kfree(rule);
15771579
}
15781580

1579-
static struct nft_trans *nft_trans_rule_add(struct nft_ctx *ctx,
1581+
static struct nft_trans *nft_trans_rule_add(struct nft_ctx *ctx, int msg_type,
15801582
struct nft_rule *rule)
15811583
{
15821584
struct nft_trans *trans;
15831585

1584-
trans = nft_trans_alloc(ctx, sizeof(struct nft_trans_rule));
1586+
trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_rule));
15851587
if (trans == NULL)
15861588
return NULL;
15871589

@@ -1703,7 +1705,8 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
17031705

17041706
if (nlh->nlmsg_flags & NLM_F_REPLACE) {
17051707
if (nft_rule_is_active_next(net, old_rule)) {
1706-
trans = nft_trans_rule_add(&ctx, old_rule);
1708+
trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE,
1709+
old_rule);
17071710
if (trans == NULL) {
17081711
err = -ENOMEM;
17091712
goto err2;
@@ -1726,7 +1729,7 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
17261729
list_add_rcu(&rule->list, &chain->rules);
17271730
}
17281731

1729-
if (nft_trans_rule_add(&ctx, rule) == NULL) {
1732+
if (nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule) == NULL) {
17301733
err = -ENOMEM;
17311734
goto err3;
17321735
}
@@ -1754,7 +1757,7 @@ nf_tables_delrule_one(struct nft_ctx *ctx, struct nft_rule *rule)
17541757
{
17551758
/* You cannot delete the same rule twice */
17561759
if (nft_rule_is_active_next(ctx->net, rule)) {
1757-
if (nft_trans_rule_add(ctx, rule) == NULL)
1760+
if (nft_trans_rule_add(ctx, NFT_MSG_DELRULE, rule) == NULL)
17581761
return -ENOMEM;
17591762
nft_rule_disactivate_next(ctx->net, rule);
17601763
return 0;
@@ -3114,37 +3117,40 @@ static int nf_tables_commit(struct sk_buff *skb)
31143117
synchronize_rcu();
31153118

31163119
list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
3117-
/* This rule was inactive in the past and just became active.
3118-
* Clear the next bit of the genmask since its meaning has
3119-
* changed, now it is the future.
3120-
*/
3121-
if (nft_rule_is_active(net, nft_trans_rule(trans))) {
3122-
nft_rule_clear(net, nft_trans_rule(trans));
3123-
nf_tables_rule_notify(skb, trans->ctx.nlh,
3120+
switch (trans->msg_type) {
3121+
case NFT_MSG_NEWRULE:
3122+
nft_rule_clear(trans->ctx.net, nft_trans_rule(trans));
3123+
nf_tables_rule_notify(trans->ctx.skb, trans->ctx.nlh,
31243124
trans->ctx.table,
31253125
trans->ctx.chain,
31263126
nft_trans_rule(trans),
31273127
NFT_MSG_NEWRULE, 0,
31283128
trans->ctx.afi->family);
31293129
nft_trans_destroy(trans);
3130-
continue;
3130+
break;
3131+
case NFT_MSG_DELRULE:
3132+
list_del_rcu(&nft_trans_rule(trans)->list);
3133+
nf_tables_rule_notify(trans->ctx.skb, trans->ctx.nlh,
3134+
trans->ctx.table,
3135+
trans->ctx.chain,
3136+
nft_trans_rule(trans), NFT_MSG_DELRULE, 0,
3137+
trans->ctx.afi->family);
3138+
break;
31313139
}
3132-
3133-
/* This rule is in the past, get rid of it */
3134-
list_del_rcu(&nft_trans_rule(trans)->list);
3135-
nf_tables_rule_notify(skb, trans->ctx.nlh,
3136-
trans->ctx.table, trans->ctx.chain,
3137-
nft_trans_rule(trans), NFT_MSG_DELRULE,
3138-
0, trans->ctx.afi->family);
31393140
}
31403141

31413142
/* Make sure we don't see any packet traversing old rules */
31423143
synchronize_rcu();
31433144

31443145
/* Now we can safely release unused old rules */
31453146
list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
3146-
nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
3147-
nft_trans_destroy(trans);
3147+
switch (trans->msg_type) {
3148+
case NFT_MSG_DELRULE:
3149+
nf_tables_rule_destroy(&trans->ctx,
3150+
nft_trans_rule(trans));
3151+
nft_trans_destroy(trans);
3152+
break;
3153+
}
31483154
}
31493155

31503156
return 0;
@@ -3156,22 +3162,28 @@ static int nf_tables_abort(struct sk_buff *skb)
31563162
struct nft_trans *trans, *next;
31573163

31583164
list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
3159-
if (!nft_rule_is_active_next(net, nft_trans_rule(trans))) {
3160-
nft_rule_clear(net, nft_trans_rule(trans));
3165+
switch (trans->msg_type) {
3166+
case NFT_MSG_NEWRULE:
3167+
list_del_rcu(&nft_trans_rule(trans)->list);
3168+
break;
3169+
case NFT_MSG_DELRULE:
3170+
nft_rule_clear(trans->ctx.net, nft_trans_rule(trans));
31613171
nft_trans_destroy(trans);
3162-
continue;
3172+
break;
31633173
}
3164-
3165-
/* This rule is inactive, get rid of it */
3166-
list_del_rcu(&nft_trans_rule(trans)->list);
31673174
}
31683175

31693176
/* Make sure we don't see any packet accessing aborted rules */
31703177
synchronize_rcu();
31713178

31723179
list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
3173-
nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
3174-
nft_trans_destroy(trans);
3180+
switch (trans->msg_type) {
3181+
case NFT_MSG_NEWRULE:
3182+
nf_tables_rule_destroy(&trans->ctx,
3183+
nft_trans_rule(trans));
3184+
nft_trans_destroy(trans);
3185+
break;
3186+
}
31753187
}
31763188

31773189
return 0;

0 commit comments

Comments
 (0)