Netdev List
 help / color / mirror / Atom feed
From: Julius Bairaktaris <julius@bairaktaris.de>
To: pablo@netfilter.org, netfilter-devel@vger.kernel.org
Cc: kadlec@netfilter.org, fw@strlen.de, coreteam@netfilter.org,
	netdev@vger.kernel.org, geldot@protonmail.com
Subject: [PATCH nf-next 3/4] netfilter: nft_flow_offload: offload a TCP flow that has no reply
Date: Thu, 10 Sep 2026 11:00:51 +0200	[thread overview]
Message-ID: <20260910090052.2034970-4-julius@bairaktaris.de> (raw)
In-Reply-To: <20260910090052.2034970-1-julius@bairaktaris.de>

From: Gary Dotzler <geldot@protonmail.com>

A connection whose reply never reaches the host cannot become assured,
and only assured TCP connections are offered to the flowtable, so every
packet of it stays on the classic path.

Offer such a connection to the flowtable in the original direction. The
reply direction follows once conntrack has seen a reply, so a flow that
starts one-directional picks it up if the path turns symmetric.

Signed-off-by: Gary Dotzler <geldot@protonmail.com>
Co-developed-by: Julius Bairaktaris <julius@bairaktaris.de>
Signed-off-by: Julius Bairaktaris <julius@bairaktaris.de>
Assisted-by: Claude:claude-opus-5
---
 include/net/netfilter/nf_conntrack_l4proto.h | 7 +++++++
 net/netfilter/nft_flow_offload.c             | 6 ++++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h
index fde2427ceb8f..a4e3d9ed7a64 100644
--- a/include/net/netfilter/nf_conntrack_l4proto.h
+++ b/include/net/netfilter/nf_conntrack_l4proto.h
@@ -208,6 +208,13 @@ static inline bool nf_conntrack_tcp_established(const struct nf_conn *ct)
 	return ct->proto.tcp.state == TCP_CONNTRACK_ESTABLISHED &&
 	       test_bit(IPS_ASSURED_BIT, &ct->status);
 }
+
+/* A flow picked up without its reply cannot become assured. */
+static inline bool nf_conntrack_tcp_unreplied(const struct nf_conn *ct)
+{
+	return ct->proto.tcp.state == TCP_CONNTRACK_ESTABLISHED &&
+	       !test_bit(IPS_SEEN_REPLY_BIT, &ct->status);
+}
 #endif
 
 #ifdef CONFIG_NF_CT_PROTO_SCTP
diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c
index 32b4281038dd..0b6be8ac3d24 100644
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -73,7 +73,8 @@ static void nft_flow_offload_eval(const struct nft_expr *expr,
 		tcph = skb_header_pointer(pkt->skb, nft_thoff(pkt),
 					  sizeof(_tcph), &_tcph);
 		if (unlikely(!tcph || tcph->fin || tcph->rst ||
-			     !nf_conntrack_tcp_established(ct)))
+			     (!nf_conntrack_tcp_established(ct) &&
+			      !nf_conntrack_tcp_unreplied(ct))))
 			goto out;
 		break;
 	case IPPROTO_UDP:
@@ -117,7 +118,8 @@ static void nft_flow_offload_eval(const struct nft_expr *expr,
 	if (tcph)
 		flow_offload_ct_tcp(ct);
 
-	__set_bit(NF_FLOW_HW_BIDIRECTIONAL, &flow->flags);
+	if (!tcph || !nf_conntrack_tcp_unreplied(ct))
+		__set_bit(NF_FLOW_HW_BIDIRECTIONAL, &flow->flags);
 	ret = flow_offload_add(flowtable, flow);
 	if (ret < 0)
 		goto err_flow_add;
-- 
2.53.0


  parent reply	other threads:[~2026-09-10  9:00 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-10  9:00 [PATCH nf-next 0/4] netfilter: offload a TCP flow whose reply is never seen Julius Bairaktaris
2026-09-10  9:00 ` [PATCH nf-next 1/4] netfilter: conntrack: pick up a TCP flow whose SYN was never answered Julius Bairaktaris
2026-09-10  9:00 ` [PATCH nf-next 2/4] netfilter: flowtable: promote a flow offloaded in one direction only Julius Bairaktaris
2026-09-10  9:00 ` Julius Bairaktaris [this message]
2026-09-10  9:00 ` [PATCH nf-next 4/4] selftests: netfilter: cover a TCP flow whose reply is never seen Julius Bairaktaris
2026-09-11 11:41 ` [PATCH nf-next 0/4] netfilter: offload " Pablo Neira Ayuso
2026-09-11 12:10   ` Julius Bairaktaris
2026-09-11 14:09     ` Pablo Neira Ayuso
2026-09-11 14:16       ` Pablo Neira Ayuso

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260910090052.2034970-4-julius@bairaktaris.de \
    --to=julius@bairaktaris.de \
    --cc=coreteam@netfilter.org \
    --cc=fw@strlen.de \
    --cc=geldot@protonmail.com \
    --cc=kadlec@netfilter.org \
    --cc=netdev@vger.kernel.org \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pablo@netfilter.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox