* [PATCH nf 2/2] netfilter: flowtable: use UDP timeout after flow teardown
@ 2024-03-18 9:57 Pablo Neira Ayuso
0 siblings, 0 replies; 3+ messages in thread
From: Pablo Neira Ayuso @ 2024-03-18 9:57 UTC (permalink / raw)
To: netfilter-devel; +Cc: cratiu, gal, ozsh, vladbu, fw, sven.auhagen
Do not subtract flow timeout from UDP timeout, simply use UDP timeout
instead. Users can tweak UDP conntrack timeouts leading to zero
conntrack timeout when handing over the flow back to classic conntrack
path.
Fixes: e5eaac2beb54 ("netfilter: flowtable: fix TCP flow teardown")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
Follow up patch after:
[nf] netfilter: flowtable: infer TCP state and timeout before flow teardown
which should have been 1/2.
net/netfilter/nf_flow_table_core.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c
index 481fe3d96bbc..21286775cb32 100644
--- a/net/netfilter/nf_flow_table_core.c
+++ b/net/netfilter/nf_flow_table_core.c
@@ -165,7 +165,7 @@ void flow_offload_route_init(struct flow_offload *flow,
}
EXPORT_SYMBOL_GPL(flow_offload_route_init);
-static s32 flow_offload_fixup_tcp(struct net *net, struct nf_conn *ct,
+static u32 flow_offload_fixup_tcp(struct net *net, struct nf_conn *ct,
enum tcp_conntrack tcp_state)
{
struct nf_tcp_net *tn = nf_tcp_pernet(net);
@@ -187,7 +187,7 @@ static void flow_offload_fixup_ct(struct nf_conn *ct)
{
struct net *net = nf_ct_net(ct);
int l4num = nf_ct_protonum(ct);
- s32 timeout;
+ u32 timeout;
if (l4num == IPPROTO_TCP) {
timeout = flow_offload_fixup_tcp(net, ct,
@@ -199,14 +199,10 @@ static void flow_offload_fixup_ct(struct nf_conn *ct)
UDP_CT_REPLIED : UDP_CT_UNREPLIED;
timeout = tn->timeouts[state];
- timeout -= tn->offload_timeout;
} else {
return;
}
- if (timeout < 0)
- timeout = 0;
-
if (nf_flow_timeout_delta(READ_ONCE(ct->timeout)) > (__s32)timeout)
WRITE_ONCE(ct->timeout, nfct_time_stamp + timeout);
}
--
2.30.2
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH nf 1/2] netfilter: flowtable: infer TCP state and timeout before flow teardown
@ 2024-03-20 9:26 Pablo Neira Ayuso
2024-03-20 9:26 ` [PATCH nf 2/2] netfilter: flowtable: use UDP timeout after " Pablo Neira Ayuso
0 siblings, 1 reply; 3+ messages in thread
From: Pablo Neira Ayuso @ 2024-03-20 9:26 UTC (permalink / raw)
To: netfilter-devel; +Cc: sven.auhagen, cratiu, ozsh, vladbu, gal
In case that either FIN or RST packet is seen, infer current TCP state
based on the TCP packet flags before setting the _TEARDOWN flag:
- FIN packets result in TCP_CONNTRACK_FIN_WAIT which uses a default
timeout of 2 minutes.
- RST packets lead to tcp_state TCP_CONNTRACK_CLOSE of 10 seconds.
Therefore, TCP established state with a low timeout is not used anymore
when handing over the flow to the classic conntrack path, otherwise a
FIN packet coming in the reply direction could re-offload this flow
again.
Fixes: e5eaac2beb54 ("netfilter: flowtable: fix TCP flow teardown")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
v2: leave things as is for the flow timeout expiration case.
No established state and _unack timeout is assumed per Sven.
include/net/netfilter/nf_flow_table.h | 1 +
net/netfilter/nf_flow_table_core.c | 38 ++++++++++++++++++++-------
net/netfilter/nf_flow_table_ip.c | 2 +-
3 files changed, 30 insertions(+), 11 deletions(-)
diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h
index a763dd327c6e..924f3720143f 100644
--- a/include/net/netfilter/nf_flow_table.h
+++ b/include/net/netfilter/nf_flow_table.h
@@ -293,6 +293,7 @@ int nf_flow_table_init(struct nf_flowtable *flow_table);
void nf_flow_table_free(struct nf_flowtable *flow_table);
void flow_offload_teardown(struct flow_offload *flow);
+void flow_offload_teardown_tcp(struct flow_offload *flow, bool fin);
void nf_flow_snat_port(const struct flow_offload *flow,
struct sk_buff *skb, unsigned int thoff,
diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c
index a0571339239c..bd880c58bfab 100644
--- a/net/netfilter/nf_flow_table_core.c
+++ b/net/netfilter/nf_flow_table_core.c
@@ -165,10 +165,16 @@ void flow_offload_route_init(struct flow_offload *flow,
}
EXPORT_SYMBOL_GPL(flow_offload_route_init);
-static void flow_offload_fixup_tcp(struct ip_ct_tcp *tcp)
+static s32 flow_offload_fixup_tcp(struct net *net, struct nf_conn *ct,
+ enum tcp_conntrack tcp_state)
{
- tcp->seen[0].td_maxwin = 0;
- tcp->seen[1].td_maxwin = 0;
+ struct nf_tcp_net *tn = nf_tcp_pernet(net);
+
+ ct->proto.tcp.state = tcp_state;
+ ct->proto.tcp.seen[0].td_maxwin = 0;
+ ct->proto.tcp.seen[1].td_maxwin = 0;
+
+ return tn->timeouts[tcp_state];
}
static void flow_offload_fixup_ct(struct nf_conn *ct)
@@ -178,12 +184,7 @@ static void flow_offload_fixup_ct(struct nf_conn *ct)
s32 timeout;
if (l4num == IPPROTO_TCP) {
- struct nf_tcp_net *tn = nf_tcp_pernet(net);
-
- flow_offload_fixup_tcp(&ct->proto.tcp);
-
- timeout = tn->timeouts[ct->proto.tcp.state];
- timeout -= tn->offload_timeout;
+ timeout = flow_offload_fixup_tcp(net, ct, ct->proto.tcp.state);
} else if (l4num == IPPROTO_UDP) {
struct nf_udp_net *tn = nf_udp_pernet(net);
enum udp_conntrack state =
@@ -346,12 +347,29 @@ static void flow_offload_del(struct nf_flowtable *flow_table,
void flow_offload_teardown(struct flow_offload *flow)
{
+ flow_offload_fixup_ct(flow->ct);
+ smp_mb__before_atomic();
clear_bit(IPS_OFFLOAD_BIT, &flow->ct->status);
set_bit(NF_FLOW_TEARDOWN, &flow->flags);
- flow_offload_fixup_ct(flow->ct);
}
EXPORT_SYMBOL_GPL(flow_offload_teardown);
+void flow_offload_teardown_tcp(struct flow_offload *flow, bool fin)
+{
+ enum tcp_conntrack tcp_state;
+
+ if (fin)
+ tcp_state = TCP_CONNTRACK_FIN_WAIT;
+ else /* rst */
+ tcp_state = TCP_CONNTRACK_CLOSE;
+
+ flow_offload_fixup_tcp(nf_ct_net(flow->ct), flow->ct, tcp_state);
+ smp_mb__before_atomic();
+ clear_bit(IPS_OFFLOAD_BIT, &flow->ct->status);
+ set_bit(NF_FLOW_TEARDOWN, &flow->flags);
+}
+EXPORT_SYMBOL_GPL(flow_offload_teardown_tcp);
+
struct flow_offload_tuple_rhash *
flow_offload_lookup(struct nf_flowtable *flow_table,
struct flow_offload_tuple *tuple)
diff --git a/net/netfilter/nf_flow_table_ip.c b/net/netfilter/nf_flow_table_ip.c
index e45fade76409..13b6c453d8bc 100644
--- a/net/netfilter/nf_flow_table_ip.c
+++ b/net/netfilter/nf_flow_table_ip.c
@@ -29,7 +29,7 @@ static int nf_flow_state_check(struct flow_offload *flow, int proto,
tcph = (void *)(skb_network_header(skb) + thoff);
if (unlikely(tcph->fin || tcph->rst)) {
- flow_offload_teardown(flow);
+ flow_offload_teardown_tcp(flow, tcph->fin);
return -1;
}
--
2.30.2
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH nf 2/2] netfilter: flowtable: use UDP timeout after flow teardown
2024-03-20 9:26 [PATCH nf 1/2] netfilter: flowtable: infer TCP state and timeout before flow teardown Pablo Neira Ayuso
@ 2024-03-20 9:26 ` Pablo Neira Ayuso
0 siblings, 0 replies; 3+ messages in thread
From: Pablo Neira Ayuso @ 2024-03-20 9:26 UTC (permalink / raw)
To: netfilter-devel; +Cc: sven.auhagen, cratiu, ozsh, vladbu, gal
Do not subtract flow timeout from UDP timeout, simply use UDP timeout
instead. Users can tweak UDP conntrack timeouts leading to zero
conntrack timeout when handing over the flow back to classic conntrack
path.
Fixes: e5eaac2beb54 ("netfilter: flowtable: fix TCP flow teardown")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
v2: no changes, just rebase on top of 1/2
net/netfilter/nf_flow_table_core.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c
index bd880c58bfab..16068ef04490 100644
--- a/net/netfilter/nf_flow_table_core.c
+++ b/net/netfilter/nf_flow_table_core.c
@@ -165,7 +165,7 @@ void flow_offload_route_init(struct flow_offload *flow,
}
EXPORT_SYMBOL_GPL(flow_offload_route_init);
-static s32 flow_offload_fixup_tcp(struct net *net, struct nf_conn *ct,
+static u32 flow_offload_fixup_tcp(struct net *net, struct nf_conn *ct,
enum tcp_conntrack tcp_state)
{
struct nf_tcp_net *tn = nf_tcp_pernet(net);
@@ -181,7 +181,7 @@ static void flow_offload_fixup_ct(struct nf_conn *ct)
{
struct net *net = nf_ct_net(ct);
int l4num = nf_ct_protonum(ct);
- s32 timeout;
+ u32 timeout;
if (l4num == IPPROTO_TCP) {
timeout = flow_offload_fixup_tcp(net, ct, ct->proto.tcp.state);
@@ -192,14 +192,10 @@ static void flow_offload_fixup_ct(struct nf_conn *ct)
UDP_CT_REPLIED : UDP_CT_UNREPLIED;
timeout = tn->timeouts[state];
- timeout -= tn->offload_timeout;
} else {
return;
}
- if (timeout < 0)
- timeout = 0;
-
if (nf_flow_timeout_delta(READ_ONCE(ct->timeout)) > (__s32)timeout)
WRITE_ONCE(ct->timeout, nfct_time_stamp + timeout);
}
--
2.30.2
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2024-03-20 9:26 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-20 9:26 [PATCH nf 1/2] netfilter: flowtable: infer TCP state and timeout before flow teardown Pablo Neira Ayuso
2024-03-20 9:26 ` [PATCH nf 2/2] netfilter: flowtable: use UDP timeout after " Pablo Neira Ayuso
-- strict thread matches above, loose matches on Subject: below --
2024-03-18 9:57 Pablo Neira Ayuso
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).