[PATCH v5 nf-next 2/3] ipvs: tcp: enable per-connection secure_tcp in state machine
From: Adriano Cordova
Date: Mon Sep 21 2026 - 17:00:50 EST
Let set_tcp_state select tcp_states_dos when the connection
carries IP_VS_CONN_F_SECURE_TCP, otherwise keep using the
global pd->tcp_state_table (the netns default / or if nomem).
Signed-off-by: Adriano Cordova <adrianox@xxxxxxxxx>
---
Changes in v5:
- Document that secure_tcp is the netns-wide default and that a service
can opt in to the hardened table with IP_VS_SVC_F_SECURE_TCP.
Documentation/networking/ipvs-sysctl.rst | 4 ++++
net/netfilter/ipvs/ip_vs_proto_tcp.c | 16 +++++++++-------
2 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/Documentation/networking/ipvs-sysctl.rst b/Documentation/networking/ipvs-sysctl.rst
index fe36f4fcd3a0..5fc6afd2d39a 100644
--- a/Documentation/networking/ipvs-sysctl.rst
+++ b/Documentation/networking/ipvs-sysctl.rst
@@ -290,6 +290,10 @@ secure_tcp - INTEGER
The value definition is the same as that of drop_entry and
drop_packet.
+ This is the network-namespace default. A virtual service can opt
+ in to the hardened table regardless of this setting by setting
+ IP_VS_SVC_F_SECURE_TCP (0x0100) in its service flags.
+
svc_lfactor - INTEGER
Possible values: -8 (larger table) .. 8 (smaller table)
diff --git a/net/netfilter/ipvs/ip_vs_proto_tcp.c b/net/netfilter/ipvs/ip_vs_proto_tcp.c
index fec0e8b47b71..3b9a2c8e9a52 100644
--- a/net/netfilter/ipvs/ip_vs_proto_tcp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c
@@ -451,11 +451,10 @@ static void tcp_timeout_change(struct ip_vs_proto_data *pd, int flags)
int on = (flags & 1); /* secure_tcp */
/*
- ** FIXME: change secure_tcp to independent sysctl var
- ** or make it per-service or per-app because it is valid
- ** for most if not for all of the applications. Something
- ** like "capabilities" (flags) for each object.
- */
+ * This remains the netns-wide default / global floor (e.g. when
+ * memory pressure kicks in). Per-service hardening is now carried
+ * by IP_VS_CONN_F_SECURE_TCP on each connection (set_tcp_state).
+ */
pd->tcp_state_table = (on ? tcp_states_dos : tcp_states);
}
@@ -479,6 +478,7 @@ set_tcp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp,
int state_idx;
int new_state = IP_VS_TCP_S_CLOSE;
int state_off = tcp_state_off[direction];
+ const struct tcp_states_t *table;
/*
* Update state offset to INPUT_ONLY if necessary
@@ -496,8 +496,10 @@ set_tcp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp,
goto tcp_state_out;
}
- new_state =
- pd->tcp_state_table[state_off+state_idx].next_state[cp->state];
+ table = pd->tcp_state_table;
+ if (cp->flags & IP_VS_CONN_F_SECURE_TCP)
+ table = tcp_states_dos;
+ new_state = table[state_off + state_idx].next_state[cp->state];
tcp_state_out:
if (new_state != cp->state) {
--
2.51.0