@@ -105,14 +105,16 @@ static void nft_ctx_init(struct nft_ctx *ctx,
105
105
ctx -> nla = nla ;
106
106
}
107
107
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 )
109
110
{
110
111
struct nft_trans * trans ;
111
112
112
113
trans = kzalloc (sizeof (struct nft_trans ) + size , GFP_KERNEL );
113
114
if (trans == NULL )
114
115
return NULL ;
115
116
117
+ trans -> msg_type = msg_type ;
116
118
trans -> ctx = * ctx ;
117
119
118
120
return trans ;
@@ -1576,12 +1578,12 @@ static void nf_tables_rule_destroy(const struct nft_ctx *ctx,
1576
1578
kfree (rule );
1577
1579
}
1578
1580
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 ,
1580
1582
struct nft_rule * rule )
1581
1583
{
1582
1584
struct nft_trans * trans ;
1583
1585
1584
- trans = nft_trans_alloc (ctx , sizeof (struct nft_trans_rule ));
1586
+ trans = nft_trans_alloc (ctx , msg_type , sizeof (struct nft_trans_rule ));
1585
1587
if (trans == NULL )
1586
1588
return NULL ;
1587
1589
@@ -1703,7 +1705,8 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
1703
1705
1704
1706
if (nlh -> nlmsg_flags & NLM_F_REPLACE ) {
1705
1707
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 );
1707
1710
if (trans == NULL ) {
1708
1711
err = - ENOMEM ;
1709
1712
goto err2 ;
@@ -1726,7 +1729,7 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
1726
1729
list_add_rcu (& rule -> list , & chain -> rules );
1727
1730
}
1728
1731
1729
- if (nft_trans_rule_add (& ctx , rule ) == NULL ) {
1732
+ if (nft_trans_rule_add (& ctx , NFT_MSG_NEWRULE , rule ) == NULL ) {
1730
1733
err = - ENOMEM ;
1731
1734
goto err3 ;
1732
1735
}
@@ -1754,7 +1757,7 @@ nf_tables_delrule_one(struct nft_ctx *ctx, struct nft_rule *rule)
1754
1757
{
1755
1758
/* You cannot delete the same rule twice */
1756
1759
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 )
1758
1761
return - ENOMEM ;
1759
1762
nft_rule_disactivate_next (ctx -> net , rule );
1760
1763
return 0 ;
@@ -3114,37 +3117,40 @@ static int nf_tables_commit(struct sk_buff *skb)
3114
3117
synchronize_rcu ();
3115
3118
3116
3119
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 ,
3124
3124
trans -> ctx .table ,
3125
3125
trans -> ctx .chain ,
3126
3126
nft_trans_rule (trans ),
3127
3127
NFT_MSG_NEWRULE , 0 ,
3128
3128
trans -> ctx .afi -> family );
3129
3129
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 ;
3131
3139
}
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 );
3139
3140
}
3140
3141
3141
3142
/* Make sure we don't see any packet traversing old rules */
3142
3143
synchronize_rcu ();
3143
3144
3144
3145
/* Now we can safely release unused old rules */
3145
3146
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
+ }
3148
3154
}
3149
3155
3150
3156
return 0 ;
@@ -3156,22 +3162,28 @@ static int nf_tables_abort(struct sk_buff *skb)
3156
3162
struct nft_trans * trans , * next ;
3157
3163
3158
3164
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 ));
3161
3171
nft_trans_destroy (trans );
3162
- continue ;
3172
+ break ;
3163
3173
}
3164
-
3165
- /* This rule is inactive, get rid of it */
3166
- list_del_rcu (& nft_trans_rule (trans )-> list );
3167
3174
}
3168
3175
3169
3176
/* Make sure we don't see any packet accessing aborted rules */
3170
3177
synchronize_rcu ();
3171
3178
3172
3179
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
+ }
3175
3187
}
3176
3188
3177
3189
return 0 ;
0 commit comments