@@ -214,6 +214,34 @@ static int nft_delchain(struct nft_ctx *ctx)
214214 return err ;
215215}
216216
217+ static void nft_rule_expr_activate (const struct nft_ctx * ctx ,
218+ struct nft_rule * rule )
219+ {
220+ struct nft_expr * expr ;
221+
222+ expr = nft_expr_first (rule );
223+ while (expr != nft_expr_last (rule ) && expr -> ops ) {
224+ if (expr -> ops -> activate )
225+ expr -> ops -> activate (ctx , expr );
226+
227+ expr = nft_expr_next (expr );
228+ }
229+ }
230+
231+ static void nft_rule_expr_deactivate (const struct nft_ctx * ctx ,
232+ struct nft_rule * rule )
233+ {
234+ struct nft_expr * expr ;
235+
236+ expr = nft_expr_first (rule );
237+ while (expr != nft_expr_last (rule ) && expr -> ops ) {
238+ if (expr -> ops -> deactivate )
239+ expr -> ops -> deactivate (ctx , expr );
240+
241+ expr = nft_expr_next (expr );
242+ }
243+ }
244+
217245static int
218246nf_tables_delrule_deactivate (struct nft_ctx * ctx , struct nft_rule * rule )
219247{
@@ -259,6 +287,7 @@ static int nft_delrule(struct nft_ctx *ctx, struct nft_rule *rule)
259287 nft_trans_destroy (trans );
260288 return err ;
261289 }
290+ nft_rule_expr_deactivate (ctx , rule );
262291
263292 return 0 ;
264293}
@@ -2238,6 +2267,13 @@ static void nf_tables_rule_destroy(const struct nft_ctx *ctx,
22382267 kfree (rule );
22392268}
22402269
2270+ static void nf_tables_rule_release (const struct nft_ctx * ctx ,
2271+ struct nft_rule * rule )
2272+ {
2273+ nft_rule_expr_deactivate (ctx , rule );
2274+ nf_tables_rule_destroy (ctx , rule );
2275+ }
2276+
22412277#define NFT_RULE_MAXEXPRS 128
22422278
22432279static struct nft_expr_info * info ;
@@ -2402,7 +2438,7 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
24022438 return 0 ;
24032439
24042440err2 :
2405- nf_tables_rule_destroy (& ctx , rule );
2441+ nf_tables_rule_release (& ctx , rule );
24062442err1 :
24072443 for (i = 0 ; i < n ; i ++ ) {
24082444 if (info [i ].ops != NULL )
@@ -4130,7 +4166,7 @@ static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,
41304166 * NFT_GOTO verdicts. This function must be called on active data objects
41314167 * from the second phase of the commit protocol.
41324168 */
4133- static void nft_data_hold (const struct nft_data * data , enum nft_data_types type )
4169+ void nft_data_hold (const struct nft_data * data , enum nft_data_types type )
41344170{
41354171 if (type == NFT_DATA_VERDICT ) {
41364172 switch (data -> verdict .code ) {
@@ -6015,10 +6051,12 @@ static int nf_tables_abort(struct net *net, struct sk_buff *skb)
60156051 case NFT_MSG_NEWRULE :
60166052 trans -> ctx .chain -> use -- ;
60176053 list_del_rcu (& nft_trans_rule (trans )-> list );
6054+ nft_rule_expr_deactivate (& trans -> ctx , nft_trans_rule (trans ));
60186055 break ;
60196056 case NFT_MSG_DELRULE :
60206057 trans -> ctx .chain -> use ++ ;
60216058 nft_clear (trans -> ctx .net , nft_trans_rule (trans ));
6059+ nft_rule_expr_activate (& trans -> ctx , nft_trans_rule (trans ));
60226060 nft_trans_destroy (trans );
60236061 break ;
60246062 case NFT_MSG_NEWSET :
@@ -6594,7 +6632,7 @@ int __nft_release_basechain(struct nft_ctx *ctx)
65946632 list_for_each_entry_safe (rule , nr , & ctx -> chain -> rules , list ) {
65956633 list_del (& rule -> list );
65966634 ctx -> chain -> use -- ;
6597- nf_tables_rule_destroy (ctx , rule );
6635+ nf_tables_rule_release (ctx , rule );
65986636 }
65996637 list_del (& ctx -> chain -> list );
66006638 ctx -> table -> use -- ;
@@ -6632,7 +6670,7 @@ static void __nft_release_tables(struct net *net)
66326670 list_for_each_entry_safe (rule , nr , & chain -> rules , list ) {
66336671 list_del (& rule -> list );
66346672 chain -> use -- ;
6635- nf_tables_rule_destroy (& ctx , rule );
6673+ nf_tables_rule_release (& ctx , rule );
66366674 }
66376675 }
66386676 list_for_each_entry_safe (flowtable , nf , & table -> flowtables , list ) {
0 commit comments