@@ -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