+++ /dev/null
-From 4914109a8e1e494c6aa9852f9e84ec77a5fc643f Mon Sep 17 00:00:00 2001
-From: Xin Long <lucien.xin@gmail.com>
-Date: Sun, 16 Jul 2023 17:09:17 -0400
-Subject: netfilter: allow exp not to be removed in nf_ct_find_expectation
-
-From: Xin Long <lucien.xin@gmail.com>
-
-commit 4914109a8e1e494c6aa9852f9e84ec77a5fc643f upstream.
-
-Currently nf_conntrack_in() calling nf_ct_find_expectation() will
-remove the exp from the hash table. However, in some scenario, we
-expect the exp not to be removed when the created ct will not be
-confirmed, like in OVS and TC conntrack in the following patches.
-
-This patch allows exp not to be removed by setting IPS_CONFIRMED
-in the status of the tmpl.
-
-Signed-off-by: Xin Long <lucien.xin@gmail.com>
-Acked-by: Aaron Conole <aconole@redhat.com>
-Acked-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- include/net/netfilter/nf_conntrack_expect.h | 2 +-
- net/netfilter/nf_conntrack_core.c | 2 +-
- net/netfilter/nf_conntrack_expect.c | 4 ++--
- net/netfilter/nft_ct.c | 2 ++
- 4 files changed, 6 insertions(+), 4 deletions(-)
-
---- a/include/net/netfilter/nf_conntrack_expect.h
-+++ b/include/net/netfilter/nf_conntrack_expect.h
-@@ -100,7 +100,7 @@ nf_ct_expect_find_get(struct net *net,
- struct nf_conntrack_expect *
- nf_ct_find_expectation(struct net *net,
- const struct nf_conntrack_zone *zone,
-- const struct nf_conntrack_tuple *tuple);
-+ const struct nf_conntrack_tuple *tuple, bool unlink);
-
- void nf_ct_unlink_expect_report(struct nf_conntrack_expect *exp,
- u32 portid, int report);
---- a/net/netfilter/nf_conntrack_core.c
-+++ b/net/netfilter/nf_conntrack_core.c
-@@ -1770,7 +1770,7 @@ init_conntrack(struct net *net, struct n
- cnet = nf_ct_pernet(net);
- if (cnet->expect_count) {
- spin_lock_bh(&nf_conntrack_expect_lock);
-- exp = nf_ct_find_expectation(net, zone, tuple);
-+ exp = nf_ct_find_expectation(net, zone, tuple, !tmpl || nf_ct_is_confirmed(tmpl));
- if (exp) {
- pr_debug("expectation arrives ct=%p exp=%p\n",
- ct, exp);
---- a/net/netfilter/nf_conntrack_expect.c
-+++ b/net/netfilter/nf_conntrack_expect.c
-@@ -171,7 +171,7 @@ EXPORT_SYMBOL_GPL(nf_ct_expect_find_get)
- struct nf_conntrack_expect *
- nf_ct_find_expectation(struct net *net,
- const struct nf_conntrack_zone *zone,
-- const struct nf_conntrack_tuple *tuple)
-+ const struct nf_conntrack_tuple *tuple, bool unlink)
- {
- struct nf_conntrack_net *cnet = nf_ct_pernet(net);
- struct nf_conntrack_expect *i, *exp = NULL;
-@@ -211,7 +211,7 @@ nf_ct_find_expectation(struct net *net,
- !refcount_inc_not_zero(&exp->master->ct_general.use)))
- return NULL;
-
-- if (exp->flags & NF_CT_EXPECT_PERMANENT) {
-+ if (exp->flags & NF_CT_EXPECT_PERMANENT || !unlink) {
- refcount_inc(&exp->use);
- return exp;
- } else if (del_timer(&exp->timeout)) {
---- a/net/netfilter/nft_ct.c
-+++ b/net/netfilter/nft_ct.c
-@@ -272,6 +272,7 @@ static void nft_ct_set_zone_eval(const s
- regs->verdict.code = NF_DROP;
- return;
- }
-+ __set_bit(IPS_CONFIRMED_BIT, &ct->status);
- }
-
- nf_ct_set(skb, ct, IP_CT_NEW);
-@@ -378,6 +379,7 @@ static bool nft_ct_tmpl_alloc_pcpu(void)
- return false;
- }
-
-+ __set_bit(IPS_CONFIRMED_BIT, &tmp->status);
- per_cpu(nft_ct_pcpu_template, cpu) = tmp;
- }
-