* [PATCH net-next] tcp: add TCP_ECN and TCP_ECN_OPTION socket options
[not found] <CGME20260909144437epcas5p282be513a761ca5aec3f2b0fefcd2ecfa@epcas5p2.samsung.com>
@ 2026-09-09 14:45 ` Irlanki Sandeep
2026-09-10 1:38 ` kernel test robot
0 siblings, 1 reply; 2+ messages in thread
From: Irlanki Sandeep @ 2026-09-09 14:45 UTC (permalink / raw)
To: netdev, bpf
Cc: davem, edumazet, kuba, pabeni, ncardwell, ast, daniel, andrii,
corbet, linux-kernel, lorenzo, maze, sporeba, motomuman,
srihari.k, g.pokhra, r.kumawat, raj.kumars, ts413.lee,
Irlanki Sandeep
Currently, ECN and Accurate ECN (AccECN) configurations in the Linux
kernel are controlled globally via the net.ipv4.tcp_ecn and
net.ipv4.tcp_ecn_option sysctl variables. This global approach lacks the
granularity required for modern multi-application runtimes.
In diverse network environments (such as mobile operating systems like
Android), different applications route their traffic over distinct
physical and virtual interfaces (cellular, Wi-Fi, VPNs, etc.). In the
wild, certain legacy network paths or misconfigured middleboxes (such as
routers, DPIs, or firewalls) are known to blackhole packets with ECN
negotiation flags in the SYN, or silently drop packets containing AccECN
option headers during active sessions.
If ECN or AccECN options are disabled globally to prevent connection
failures on a single broken path, the system loses the low-latency and
throughput benefits of L4S across all other compliant network paths.
Conversely, if enabled globally, connections on broken paths will suffer
severe packet loss and timeout regressions.
Introduce two new TCP socket options to enable granular, per-connection
dynamic adaptation based on runtime network metrics and diagnostics:
1. TCP_ECN: Exposes per-socket configuration of ECN negotiation modes
(0-5, corresponding to existing sysctl modes, or 255/UNSPEC to
revert to the global sysctl default). This allows an application or
framework to selectively disable ECN negotiation on sockets where
path anomalies are detected.
2. TCP_ECN_OPTION: Exposes per-socket control of AccECN option sending
frequency (0-3, or 255/UNSPEC to revert to the global sysctl default).
This allows disabling the option headers on active sockets if
middlebox dropping behavior is observed after session establishment.
Provide helper functions tcp_ecn_mode_eff() and tcp_accecn_option_eff()
to dynamically evaluate per-socket overrides with transparent fallback
to system sysctl defaults. Also expose these options via BPF sockops
and update documentation and BPF selftests accordingly.
Signed-off-by: Irlanki Sandeep <irlanki.s@samsung.com>
---
Documentation/networking/ip-sysctl.rst | 37 +++++++++++++++++++
include/linux/tcp.h | 7 ++++
include/net/tcp_ecn.h | 24 +++++++++++-
include/uapi/linux/bpf.h | 3 +-
include/uapi/linux/tcp.h | 2 +
net/core/filter.c | 2 +
net/ipv4/tcp.c | 22 +++++++++++
net/ipv4/tcp_input.c | 4 +-
net/ipv4/tcp_output.c | 6 +--
tools/include/uapi/linux/bpf.h | 3 +-
tools/include/uapi/linux/tcp.h | 3 +-
.../selftests/bpf/progs/setget_sockopt.c | 2 +
12 files changed, 106 insertions(+), 9 deletions(-)
diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst
index 208f46967..2e55d9e2e 100644
--- a/Documentation/networking/ip-sysctl.rst
+++ b/Documentation/networking/ip-sysctl.rst
@@ -528,6 +528,43 @@ tcp_ecn_fallback - BOOLEAN
Default: 1 (enabled)
+tcp_ecn (socket option) - TCP_ECN
+ Per-socket control of ECN mode, allowing per-connection override of the
+ tcp_ecn sysctl setting. This enables L4S (Low Latency, Low Loss, Scalable
+ Throughput) configuration on a per-socket basis.
+
+ Setting this socket option to any value except 255 will override the
+ system-wide tcp_ecn sysctl for that particular socket. A value of 255
+ (TCP_ECN_MODE_UNSPEC) means use the system default sysctl value.
+
+ Possible values: 0-5 (see tcp_ecn sysctl description above), or 255 to
+ use the system default (sysctl_tcp_ecn).
+
+ Example::
+
+ int val = 3; /* AccECN mode */
+ setsockopt(fd, SOL_TCP, TCP_ECN, &val, sizeof(val));
+
+ Default: 255 (unspecified - uses tcp_ecn sysctl value)
+
+tcp_ecn_option (socket option) - TCP_ECN_OPTION
+ Per-socket control of Accurate ECN (AccECN) option sending behavior,
+ allowing per-connection override of the tcp_ecn_option sysctl setting.
+
+ Setting this socket option to any value except 255 will override the
+ system-wide tcp_ecn_option sysctl for that particular socket. A value of
+ 255 (TCP_ACCECN_OPTION_UNSPEC) means use the system default sysctl value.
+
+ Possible values: 0-3 (see tcp_ecn_option sysctl description above), or 255
+ to use the system default (sysctl_tcp_ecn_option).
+
+ Example::
+
+ int val = 2; /* Send AccECN option on every packet */
+ setsockopt(fd, SOL_TCP, TCP_ECN_OPTION, &val, sizeof(val));
+
+ Default: 255 (unspecified - uses tcp_ecn_option sysctl value)
+
tcp_fack - BOOLEAN
This is a legacy option, it has no effect anymore.
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 6a8c77719..7cb1e765f 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -289,6 +289,13 @@ struct tcp_sock {
* sacked_out > 0)
*/
u8 ecn_flags; /* ECN status bits. */
+ u8 ecn_mode; /* Per-socket ECN mode override
+ * (TCP_ECN_MODE_UNSPEC = use sysctl)
+ */
+ u8 ecn_option; /* Per-socket AccECN option override
+ * (TCP_ACCECN_OPTION_UNSPEC = use sysctl)
+ */
+
__cacheline_group_end(tcp_sock_write_tx);
/* TXRX read-write hotpath cache lines */
diff --git a/include/net/tcp_ecn.h b/include/net/tcp_ecn.h
index 865d5c5a7..931e08771 100644
--- a/include/net/tcp_ecn.h
+++ b/include/net/tcp_ecn.h
@@ -22,6 +22,7 @@ enum tcp_ecn_mode {
TCP_ECN_IN_ACCECN_OUT_ACCECN = 3,
TCP_ECN_IN_ACCECN_OUT_ECN = 4,
TCP_ECN_IN_ACCECN_OUT_NOECN = 5,
+ TCP_ECN_MODE_UNSPEC = 255, /* Use sysctl default (per-socket) */
};
/* AccECN option sending when AccECN has been successfully negotiated */
@@ -30,8 +31,29 @@ enum tcp_accecn_option {
TCP_ACCECN_OPTION_MINIMUM = 1,
TCP_ACCECN_OPTION_FULL = 2,
TCP_ACCECN_OPTION_PERSIST = 3,
+ TCP_ACCECN_OPTION_UNSPEC = 255, /* Use sysctl default (per-socket) */
};
+/* Resolve the effective ECN mode: per-socket override or sysctl fallback */
+static inline u8 tcp_ecn_mode_eff(const struct sock *sk)
+{
+ u8 mode = tcp_sk(sk)->ecn_mode;
+
+ if (mode == TCP_ECN_MODE_UNSPEC)
+ return READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_ecn);
+ return mode;
+}
+
+/* Resolve the effective AccECN option: per-socket override or sysctl fallback */
+static inline u8 tcp_accecn_option_eff(const struct sock *sk)
+{
+ u8 opt = tcp_sk(sk)->ecn_option;
+
+ if (opt == TCP_ACCECN_OPTION_UNSPEC)
+ return READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_ecn_option);
+ return opt;
+}
+
/* Apply either ECT(0) or ECT(1) based on TCP_CONG_ECT_1_NEGOTIATION flag */
static inline void INET_ECN_xmit_ect_1_negotiation(struct sock *sk)
{
@@ -599,7 +621,7 @@ static inline void tcp_ecn_send_syn(struct sock *sk, struct sk_buff *skb)
struct tcp_sock *tp = tcp_sk(sk);
bool bpf_needs_ecn = tcp_bpf_ca_needs_ecn(sk);
bool use_ecn, use_accecn;
- u8 tcp_ecn = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_ecn);
+ u8 tcp_ecn = tcp_ecn_mode_eff(sk);
use_accecn = tcp_ecn == TCP_ECN_IN_ACCECN_OUT_ACCECN ||
tcp_ca_needs_accecn(sk);
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 732b35cc0..c58b1633b 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -2985,7 +2985,8 @@ union bpf_attr {
* **TCP_SYNCNT**, **TCP_USER_TIMEOUT**, **TCP_NOTSENT_LOWAT**,
* **TCP_NODELAY**, **TCP_MAXSEG**, **TCP_WINDOW_CLAMP**,
* **TCP_THIN_LINEAR_TIMEOUTS**, **TCP_BPF_DELACK_MAX**,
- * **TCP_BPF_RTO_MIN**, **TCP_BPF_SOCK_OPS_CB_FLAGS**.
+ * **TCP_BPF_RTO_MIN**, **TCP_BPF_SOCK_OPS_CB_FLAGS**,
+ * **TCP_ECN**, **TCP_ECN_OPTION**.
* * **IPPROTO_IP**, which supports *optname* **IP_TOS**.
* * **IPPROTO_IPV6**, which supports the following *optname*\ s:
* **IPV6_TCLASS**, **IPV6_AUTOFLOWLABEL**.
diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h
index 03772dd4d..01ebb348b 100644
--- a/include/uapi/linux/tcp.h
+++ b/include/uapi/linux/tcp.h
@@ -142,6 +142,8 @@ enum {
#define TCP_RTO_MAX_MS 44 /* max rto time in ms */
#define TCP_RTO_MIN_US 45 /* min rto time in us */
#define TCP_DELACK_MAX_US 46 /* max delayed ack time in us */
+#define TCP_ECN 47 /* Per-socket ECN mode (0-5, 255=use sysctl) */
+#define TCP_ECN_OPTION 48 /* Per-socket AccECN option (0-3, 255=use sysctl) */
#define TCP_REPAIR_ON 1
#define TCP_REPAIR_OFF 0
diff --git a/net/core/filter.c b/net/core/filter.c
index 61940e753..993b31e10 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -5670,6 +5670,8 @@ static int sol_tcp_sockopt(struct sock *sk, int optname,
case TCP_NOTSENT_LOWAT:
case TCP_SAVE_SYN:
case TCP_RTO_MAX_MS:
+ case TCP_ECN:
+ case TCP_ECN_OPTION:
if (*optlen != sizeof(int))
return -EINVAL;
break;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 1c867a302..fb376a97f 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -463,6 +463,8 @@ void tcp_init_sock(struct sock *sk)
tp->tsoffset = 0;
tp->rack.reo_wnd_steps = 1;
+ tp->ecn_mode = TCP_ECN_MODE_UNSPEC;
+ tp->ecn_option = TCP_ACCECN_OPTION_UNSPEC;
sk->sk_write_space = sk_stream_write_space;
sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
@@ -4160,6 +4162,18 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname,
tcp_enable_tx_delay(sk, val);
WRITE_ONCE(tp->tcp_tx_delay, val);
break;
+ case TCP_ECN:
+ if (val != TCP_ECN_MODE_UNSPEC && (val < 0 || val > TCP_ECN_IN_ACCECN_OUT_NOECN))
+ err = -EINVAL;
+ else
+ WRITE_ONCE(tp->ecn_mode, val);
+ break;
+ case TCP_ECN_OPTION:
+ if (val != TCP_ACCECN_OPTION_UNSPEC && (val < 0 || val > TCP_ACCECN_OPTION_PERSIST))
+ err = -EINVAL;
+ else
+ WRITE_ONCE(tp->ecn_option, val);
+ break;
default:
err = -ENOPROTOOPT;
break;
@@ -4842,6 +4856,12 @@ int do_tcp_getsockopt(struct sock *sk, int level,
case TCP_DELACK_MAX_US:
val = jiffies_to_usecs(READ_ONCE(inet_csk(sk)->icsk_delack_max));
break;
+ case TCP_ECN:
+ val = READ_ONCE(tp->ecn_mode);
+ break;
+ case TCP_ECN_OPTION:
+ val = READ_ONCE(tp->ecn_option);
+ break;
default:
return -ENOPROTOOPT;
}
@@ -5256,6 +5276,8 @@ static void __init tcp_struct_check(void)
CACHELINE_ASSERT_GROUP_MEMBER(struct tcp_sock, tcp_sock_write_tx, tsorted_sent_queue);
CACHELINE_ASSERT_GROUP_MEMBER(struct tcp_sock, tcp_sock_write_tx, highest_sack);
CACHELINE_ASSERT_GROUP_MEMBER(struct tcp_sock, tcp_sock_write_tx, ecn_flags);
+ CACHELINE_ASSERT_GROUP_MEMBER(struct tcp_sock, tcp_sock_write_tx, ecn_mode);
+ CACHELINE_ASSERT_GROUP_MEMBER(struct tcp_sock, tcp_sock_write_tx, ecn_option);
/* TXRX read-write hotpath cache lines */
CACHELINE_ASSERT_GROUP_MEMBER(struct tcp_sock, tcp_sock_write_txrx, pred_flags);
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 0f60a1dbf..b7dea787f 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -7463,7 +7463,7 @@ static void tcp_ecn_create_request(struct request_sock *req,
u32 ecn_ok_dst;
if (tcp_accecn_syn_requested(th) &&
- (READ_ONCE(net->ipv4.sysctl_tcp_ecn) >= 3 ||
+ (tcp_ecn_mode_eff(listen_sk) >= 3 ||
tcp_ca_needs_accecn(listen_sk))) {
inet_rsk(req)->ecn_ok = 1;
tcp_rsk(req)->accecn_ok = 1;
@@ -7477,7 +7477,7 @@ static void tcp_ecn_create_request(struct request_sock *req,
ect = !INET_ECN_is_not_ect(TCP_SKB_CB(skb)->ip_dsfield);
ecn_ok_dst = dst_feature(dst, DST_FEATURE_ECN_MASK);
- ecn_ok = READ_ONCE(net->ipv4.sysctl_tcp_ecn) || ecn_ok_dst;
+ ecn_ok = tcp_ecn_mode_eff(listen_sk) || ecn_ok_dst;
if (((!ect || th->res1 || th->ae) && ecn_ok) ||
tcp_ca_needs_ecn(listen_sk) ||
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 00417a429..82b96c401 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1045,7 +1045,7 @@ static unsigned int tcp_syn_options(struct sock *sk, struct sk_buff *skb,
if (unlikely((TCP_SKB_CB(skb)->tcp_flags & TCPHDR_ACK) &&
tcp_ecn_mode_accecn(tp) &&
inet_csk(sk)->icsk_retransmits < 2 &&
- READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_ecn_option) &&
+ tcp_accecn_option_eff(sk) &&
remaining >= TCPOLEN_ACCECN_BASE)) {
opts->use_synack_ecn_bytes = 1;
remaining -= tcp_options_fit_accecn(opts, 0, remaining);
@@ -1133,7 +1133,7 @@ static unsigned int tcp_synack_options(const struct sock *sk,
smc_set_option_cond(tcp_sk(sk), ireq, opts, &remaining);
if (treq->accecn_ok &&
- READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_ecn_option) &&
+ tcp_accecn_option_eff(sk) &&
synack_type != TCP_SYNACK_RETRANS && remaining >= TCPOLEN_ACCECN_BASE) {
opts->use_synack_ecn_bytes = 1;
remaining -= tcp_options_fit_accecn(opts, 0, remaining);
@@ -1221,7 +1221,7 @@ static unsigned int tcp_established_options(struct sock *sk, struct sk_buff *skb
}
if (tcp_ecn_mode_accecn(tp)) {
- int ecn_opt = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_ecn_option);
+ int ecn_opt = tcp_accecn_option_eff(sk);
if (ecn_opt && tp->saw_accecn_opt &&
(ecn_opt >= TCP_ACCECN_OPTION_PERSIST ||
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 732b35cc0..c58b1633b 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -2985,7 +2985,8 @@ union bpf_attr {
* **TCP_SYNCNT**, **TCP_USER_TIMEOUT**, **TCP_NOTSENT_LOWAT**,
* **TCP_NODELAY**, **TCP_MAXSEG**, **TCP_WINDOW_CLAMP**,
* **TCP_THIN_LINEAR_TIMEOUTS**, **TCP_BPF_DELACK_MAX**,
- * **TCP_BPF_RTO_MIN**, **TCP_BPF_SOCK_OPS_CB_FLAGS**.
+ * **TCP_BPF_RTO_MIN**, **TCP_BPF_SOCK_OPS_CB_FLAGS**,
+ * **TCP_ECN**, **TCP_ECN_OPTION**.
* * **IPPROTO_IP**, which supports *optname* **IP_TOS**.
* * **IPPROTO_IPV6**, which supports the following *optname*\ s:
* **IPV6_TCLASS**, **IPV6_AUTOFLOWLABEL**.
diff --git a/tools/include/uapi/linux/tcp.h b/tools/include/uapi/linux/tcp.h
index 13ceeb395..4f52b9df4 100644
--- a/tools/include/uapi/linux/tcp.h
+++ b/tools/include/uapi/linux/tcp.h
@@ -128,7 +128,8 @@ enum {
#define TCP_CM_INQ TCP_INQ
#define TCP_TX_DELAY 37 /* delay outgoing packets by XX usec */
-
+#define TCP_ECN 47 /* Per-socket ECN mode (0-5, 255=use sysctl) */
+#define TCP_ECN_OPTION 48 /* Per-socket AccECN option (0-3, 255=use sysctl) */
#define TCP_REPAIR_ON 1
#define TCP_REPAIR_OFF 0
diff --git a/tools/testing/selftests/bpf/progs/setget_sockopt.c b/tools/testing/selftests/bpf/progs/setget_sockopt.c
index d96e99b67..fb97fa0bc 100644
--- a/tools/testing/selftests/bpf/progs/setget_sockopt.c
+++ b/tools/testing/selftests/bpf/progs/setget_sockopt.c
@@ -64,6 +64,8 @@ static const struct sockopt_test sol_tcp_tests[] = {
{ .opt = TCP_BPF_DELACK_MAX, .new = 30000, .expected = 30000, },
{ .opt = TCP_BPF_RTO_MIN, .new = 30000, .expected = 30000, },
{ .opt = TCP_RTO_MAX_MS, .new = 2000, .expected = 2000, },
+ { .opt = TCP_ECN, .new = 3, .expected = 3, .restore = 255, },
+ { .opt = TCP_ECN_OPTION, .new = 2, .expected = 2, .restore = 255, },
{ .opt = 0, },
};
base-commit: 548b86839f7fb819a4d6c83b71c73ec378d24275
--
2.34.1
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH net-next] tcp: add TCP_ECN and TCP_ECN_OPTION socket options
2026-09-09 14:45 ` [PATCH net-next] tcp: add TCP_ECN and TCP_ECN_OPTION socket options Irlanki Sandeep
@ 2026-09-10 1:38 ` kernel test robot
0 siblings, 0 replies; 2+ messages in thread
From: kernel test robot @ 2026-09-10 1:38 UTC (permalink / raw)
To: Irlanki Sandeep, netdev, bpf
Cc: oe-kbuild-all, davem, edumazet, kuba, pabeni, ncardwell, ast,
daniel, andrii, corbet, linux-kernel, lorenzo, maze, sporeba,
motomuman, srihari.k, g.pokhra, r.kumawat, raj.kumars, ts413.lee,
Irlanki Sandeep
Hi Irlanki,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 548b86839f7fb819a4d6c83b71c73ec378d24275]
url: https://github.com/intel-lab-lkp/linux/commits/Irlanki-Sandeep/tcp-add-TCP_ECN-and-TCP_ECN_OPTION-socket-options/20260909-201557
base: 548b86839f7fb819a4d6c83b71c73ec378d24275
patch link: https://lore.kernel.org/r/20260909144557.800676-1-irlanki.s%40samsung.com
patch subject: [PATCH net-next] tcp: add TCP_ECN and TCP_ECN_OPTION socket options
config: i386-randconfig-141-20260910 (https://download.01.org/0day-ci/archive/20260910/202609100957.cYRwpjGl-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.4.0-5) 12.4.0
smatch: v0.5.0-9187-g5189e3fb
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260910/202609100957.cYRwpjGl-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202609100957.cYRwpjGl-lkp@intel.com/
All warnings (new ones prefixed by >>):
net/ipv4/tcp_input.c: In function 'tcp_ecn_create_request':
>> net/ipv4/tcp_input.c:7460:27: warning: unused variable 'net' [-Wunused-variable]
7460 | const struct net *net = sock_net(listen_sk);
| ^~~
vim +/net +7460 net/ipv4/tcp_input.c
1fb6f159fd21c64 Octavian Purdila 2014-06-25 7436
d82bd1229885d55 Florian Westphal 2014-09-29 7437 /* RFC3168 : 6.1.1 SYN packets must not have ECT/ECN bits set
d82bd1229885d55 Florian Westphal 2014-09-29 7438 *
d82bd1229885d55 Florian Westphal 2014-09-29 7439 * If we receive a SYN packet with these bits set, it means a
d82bd1229885d55 Florian Westphal 2014-09-29 7440 * network is playing bad games with TOS bits. In order to
d82bd1229885d55 Florian Westphal 2014-09-29 7441 * avoid possible false congestion notifications, we disable
f4e715c3254e3c0 stephen hemminger 2014-10-29 7442 * TCP ECN negotiation.
d82bd1229885d55 Florian Westphal 2014-09-29 7443 *
d82bd1229885d55 Florian Westphal 2014-09-29 7444 * Exception: tcp_ca wants ECN. This is required for DCTCP
843c2fdf7a12951 Florian Westphal 2015-01-30 7445 * congestion control: Linux DCTCP asserts ECT on all packets,
843c2fdf7a12951 Florian Westphal 2015-01-30 7446 * including SYN, which is most optimal solution; however,
843c2fdf7a12951 Florian Westphal 2015-01-30 7447 * others, such as FreeBSD do not.
f6fee16dbbe3fe4 Tilmans, Olivier (Nokia - BE/Antwerp 2019-04-03 7448) *
f6fee16dbbe3fe4 Tilmans, Olivier (Nokia - BE/Antwerp 2019-04-03 7449) * Exception: At least one of the reserved bits of the TCP header (th->res1) is
f6fee16dbbe3fe4 Tilmans, Olivier (Nokia - BE/Antwerp 2019-04-03 7450) * set, indicating the use of a future TCP extension (such as AccECN). See
f6fee16dbbe3fe4 Tilmans, Olivier (Nokia - BE/Antwerp 2019-04-03 7451) * RFC8311 §4.3 which updates RFC3168 to allow the development of such
f6fee16dbbe3fe4 Tilmans, Olivier (Nokia - BE/Antwerp 2019-04-03 7452) * extensions.
d82bd1229885d55 Florian Westphal 2014-09-29 7453 */
d82bd1229885d55 Florian Westphal 2014-09-29 7454 static void tcp_ecn_create_request(struct request_sock *req,
d82bd1229885d55 Florian Westphal 2014-09-29 7455 const struct sk_buff *skb,
f7b3bec6f5167ef Florian Westphal 2014-11-03 7456 const struct sock *listen_sk,
f7b3bec6f5167ef Florian Westphal 2014-11-03 7457 const struct dst_entry *dst)
d82bd1229885d55 Florian Westphal 2014-09-29 7458 {
d82bd1229885d55 Florian Westphal 2014-09-29 7459 const struct tcphdr *th = tcp_hdr(skb);
d82bd1229885d55 Florian Westphal 2014-09-29 @7460 const struct net *net = sock_net(listen_sk);
d82bd1229885d55 Florian Westphal 2014-09-29 7461 bool th_ecn = th->ece && th->cwr;
843c2fdf7a12951 Florian Westphal 2015-01-30 7462 bool ect, ecn_ok;
c3a8d9474684d39 Daniel Borkmann 2015-08-31 7463 u32 ecn_ok_dst;
d82bd1229885d55 Florian Westphal 2014-09-29 7464
3cae34274c79e0c Ilpo Järvinen 2025-09-16 7465 if (tcp_accecn_syn_requested(th) &&
4ea2ce8e35e36ab Irlanki Sandeep 2026-09-09 7466 (tcp_ecn_mode_eff(listen_sk) >= 3 ||
100f946b8d44b64 Chia-Yu Chang 2026-01-31 7467 tcp_ca_needs_accecn(listen_sk))) {
3cae34274c79e0c Ilpo Järvinen 2025-09-16 7468 inet_rsk(req)->ecn_ok = 1;
3cae34274c79e0c Ilpo Järvinen 2025-09-16 7469 tcp_rsk(req)->accecn_ok = 1;
3cae34274c79e0c Ilpo Järvinen 2025-09-16 7470 tcp_rsk(req)->syn_ect_rcv = TCP_SKB_CB(skb)->ip_dsfield &
3cae34274c79e0c Ilpo Järvinen 2025-09-16 7471 INET_ECN_MASK;
3cae34274c79e0c Ilpo Järvinen 2025-09-16 7472 return;
3cae34274c79e0c Ilpo Järvinen 2025-09-16 7473 }
3cae34274c79e0c Ilpo Järvinen 2025-09-16 7474
d82bd1229885d55 Florian Westphal 2014-09-29 7475 if (!th_ecn)
d82bd1229885d55 Florian Westphal 2014-09-29 7476 return;
d82bd1229885d55 Florian Westphal 2014-09-29 7477
d82bd1229885d55 Florian Westphal 2014-09-29 7478 ect = !INET_ECN_is_not_ect(TCP_SKB_CB(skb)->ip_dsfield);
c3a8d9474684d39 Daniel Borkmann 2015-08-31 7479 ecn_ok_dst = dst_feature(dst, DST_FEATURE_ECN_MASK);
4ea2ce8e35e36ab Irlanki Sandeep 2026-09-09 7480 ecn_ok = tcp_ecn_mode_eff(listen_sk) || ecn_ok_dst;
d82bd1229885d55 Florian Westphal 2014-09-29 7481
3cae34274c79e0c Ilpo Järvinen 2025-09-16 7482 if (((!ect || th->res1 || th->ae) && ecn_ok) ||
3cae34274c79e0c Ilpo Järvinen 2025-09-16 7483 tcp_ca_needs_ecn(listen_sk) ||
91b5b21c7c16899 Lawrence Brakmo 2017-06-30 7484 (ecn_ok_dst & DST_FEATURE_ECN_CA) ||
91b5b21c7c16899 Lawrence Brakmo 2017-06-30 7485 tcp_bpf_ca_needs_ecn((struct sock *)req))
d82bd1229885d55 Florian Westphal 2014-09-29 7486 inet_rsk(req)->ecn_ok = 1;
d82bd1229885d55 Florian Westphal 2014-09-29 7487 }
d82bd1229885d55 Florian Westphal 2014-09-29 7488
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-09-10 1:40 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <CGME20260909144437epcas5p282be513a761ca5aec3f2b0fefcd2ecfa@epcas5p2.samsung.com>
2026-09-09 14:45 ` [PATCH net-next] tcp: add TCP_ECN and TCP_ECN_OPTION socket options Irlanki Sandeep
2026-09-10 1:38 ` kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®