]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
netfilter: nf_tables_offload: release flow_rule on error from commit path
authorPablo Neira Ayuso <pablo@netfilter.org>
Thu, 14 Nov 2019 13:17:24 +0000 (14:17 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 17 Jan 2020 18:48:32 +0000 (19:48 +0100)
commit 23403cd8898dbc9808d3eb2f63bc1db8a340b751 upstream.

If hardware offload commit path fails, release all flow_rule objects.

Fixes: c9626a2cbdb2 ("netfilter: nf_tables: add hardware offload support")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/netfilter/nf_tables_offload.c

index e743f811245f664bd67d175322dc286cae244740..96a64e7594a51d9f3aaf825c4f1e3d3be8e9fa2b 100644 (file)
@@ -358,14 +358,14 @@ int nft_flow_rule_offload_commit(struct net *net)
                                continue;
 
                        if (trans->ctx.flags & NLM_F_REPLACE ||
-                           !(trans->ctx.flags & NLM_F_APPEND))
-                               return -EOPNOTSUPP;
-
+                           !(trans->ctx.flags & NLM_F_APPEND)) {
+                               err = -EOPNOTSUPP;
+                               break;
+                       }
                        err = nft_flow_offload_rule(trans->ctx.chain,
                                                    nft_trans_rule(trans),
                                                    nft_trans_flow_rule(trans),
                                                    FLOW_CLS_REPLACE);
-                       nft_flow_rule_destroy(nft_trans_flow_rule(trans));
                        break;
                case NFT_MSG_DELRULE:
                        if (!(trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD))
@@ -379,7 +379,23 @@ int nft_flow_rule_offload_commit(struct net *net)
                }
 
                if (err)
-                       return err;
+                       break;
+       }
+
+       list_for_each_entry(trans, &net->nft.commit_list, list) {
+               if (trans->ctx.family != NFPROTO_NETDEV)
+                       continue;
+
+               switch (trans->msg_type) {
+               case NFT_MSG_NEWRULE:
+                       if (!(trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD))
+                               continue;
+
+                       nft_flow_rule_destroy(nft_trans_flow_rule(trans));
+                       break;
+               default:
+                       break;
+               }
        }
 
        return err;