@@ -169,7 +169,8 @@ static void nft_trans_destroy(struct nft_trans *trans)
169169 kfree (trans );
170170}
171171
172- static void nft_set_trans_bind (const struct nft_ctx * ctx , struct nft_set * set )
172+ static void __nft_set_trans_bind (const struct nft_ctx * ctx , struct nft_set * set ,
173+ bool bind )
173174{
174175 struct nftables_pernet * nft_net ;
175176 struct net * net = ctx -> net ;
@@ -183,17 +184,28 @@ static void nft_set_trans_bind(const struct nft_ctx *ctx, struct nft_set *set)
183184 switch (trans -> msg_type ) {
184185 case NFT_MSG_NEWSET :
185186 if (nft_trans_set (trans ) == set )
186- nft_trans_set_bound (trans ) = true ;
187+ nft_trans_set_bound (trans ) = bind ;
187188 break ;
188189 case NFT_MSG_NEWSETELEM :
189190 if (nft_trans_elem_set (trans ) == set )
190- nft_trans_elem_set_bound (trans ) = true ;
191+ nft_trans_elem_set_bound (trans ) = bind ;
191192 break ;
192193 }
193194 }
194195}
195196
196- static void nft_chain_trans_bind (const struct nft_ctx * ctx , struct nft_chain * chain )
197+ static void nft_set_trans_bind (const struct nft_ctx * ctx , struct nft_set * set )
198+ {
199+ return __nft_set_trans_bind (ctx , set , true);
200+ }
201+
202+ static void nft_set_trans_unbind (const struct nft_ctx * ctx , struct nft_set * set )
203+ {
204+ return __nft_set_trans_bind (ctx , set , false);
205+ }
206+
207+ static void __nft_chain_trans_bind (const struct nft_ctx * ctx ,
208+ struct nft_chain * chain , bool bind )
197209{
198210 struct nftables_pernet * nft_net ;
199211 struct net * net = ctx -> net ;
@@ -207,16 +219,22 @@ static void nft_chain_trans_bind(const struct nft_ctx *ctx, struct nft_chain *ch
207219 switch (trans -> msg_type ) {
208220 case NFT_MSG_NEWCHAIN :
209221 if (nft_trans_chain (trans ) == chain )
210- nft_trans_chain_bound (trans ) = true ;
222+ nft_trans_chain_bound (trans ) = bind ;
211223 break ;
212224 case NFT_MSG_NEWRULE :
213225 if (trans -> ctx .chain == chain )
214- nft_trans_rule_bound (trans ) = true ;
226+ nft_trans_rule_bound (trans ) = bind ;
215227 break ;
216228 }
217229 }
218230}
219231
232+ static void nft_chain_trans_bind (const struct nft_ctx * ctx ,
233+ struct nft_chain * chain )
234+ {
235+ __nft_chain_trans_bind (ctx , chain , true);
236+ }
237+
220238int nf_tables_bind_chain (const struct nft_ctx * ctx , struct nft_chain * chain )
221239{
222240 if (!nft_chain_binding (chain ))
@@ -235,6 +253,11 @@ int nf_tables_bind_chain(const struct nft_ctx *ctx, struct nft_chain *chain)
235253 return 0 ;
236254}
237255
256+ void nf_tables_unbind_chain (const struct nft_ctx * ctx , struct nft_chain * chain )
257+ {
258+ __nft_chain_trans_bind (ctx , chain , false);
259+ }
260+
238261static int nft_netdev_register_hooks (struct net * net ,
239262 struct list_head * hook_list )
240263{
@@ -3884,7 +3907,7 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
38843907 if (flow )
38853908 nft_flow_rule_destroy (flow );
38863909err_release_rule :
3887- nft_rule_expr_deactivate (& ctx , rule , NFT_TRANS_PREPARE );
3910+ nft_rule_expr_deactivate (& ctx , rule , NFT_TRANS_PREPARE_ERROR );
38883911 nf_tables_rule_destroy (& ctx , rule );
38893912err_release_expr :
38903913 for (i = 0 ; i < n ; i ++ ) {
@@ -5183,6 +5206,13 @@ void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
51835206 enum nft_trans_phase phase )
51845207{
51855208 switch (phase ) {
5209+ case NFT_TRANS_PREPARE_ERROR :
5210+ nft_set_trans_unbind (ctx , set );
5211+ if (nft_set_is_anonymous (set ))
5212+ nft_deactivate_next (ctx -> net , set );
5213+
5214+ set -> use -- ;
5215+ break ;
51865216 case NFT_TRANS_PREPARE :
51875217 if (nft_set_is_anonymous (set ))
51885218 nft_deactivate_next (ctx -> net , set );
@@ -7701,6 +7731,7 @@ void nf_tables_deactivate_flowtable(const struct nft_ctx *ctx,
77017731 enum nft_trans_phase phase )
77027732{
77037733 switch (phase ) {
7734+ case NFT_TRANS_PREPARE_ERROR :
77047735 case NFT_TRANS_PREPARE :
77057736 case NFT_TRANS_ABORT :
77067737 case NFT_TRANS_RELEASE :
0 commit comments