aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_input.c
diff options
context:
space:
mode:
authorTilmans, Olivier (Nokia - BE/Antwerp) <olivier.tilmans@nokia-bell-labs.com>2019-04-03 09:49:42 -0400
committerDavid S. Miller <davem@davemloft.net>2019-04-04 20:43:48 -0400
commitf6fee16dbbe3fe4f942858192b88507c1f2f21ce (patch)
tree4d165c2950ea5b9947d13274db2debb7a8188475 /net/ipv4/tcp_input.c
parent6124d0670d0b610df3b86f7815c5358cb3124b34 (diff)
tcp: Accept ECT on SYN in the presence of RFC8311
Linux currently disable ECN for incoming connections when the SYN requests ECN and the IP header has ECT(0)/ECT(1) set, as some networks were reportedly mangling the ToS byte, hence could later trigger false congestion notifications. RFC8311 §4.3 relaxes RFC3168's requirements such that ECT can be set one TCP control packets (including SYNs). The main benefit of this is the decreased probability of losing a SYN in a congested ECN-capable network (i.e., it avoids the initial 1s timeout). Additionally, this allows the development of newer TCP extensions, such as AccECN. This patch relaxes the previous check, by enabling ECN on incoming connections using SYN+ECT if at least one bit of the reserved flags of the TCP header is set. Such bit would indicate that the sender of the SYN is using a newer TCP feature than what the host implements, such as AccECN, and is thus implementing RFC8311. This enables end-hosts not supporting such extensions to still negociate ECN, and to have some of the benefits of using ECN on control packets. Signed-off-by: Olivier Tilmans <olivier.tilmans@nokia-bell-labs.com> Suggested-by: Bob Briscoe <research@bobbriscoe.net> Cc: Koen De Schepper <koen.de_schepper@nokia-bell-labs.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Acked-by: Neal Cardwell <ncardwell@google.com> Acked-by: Yuchung Cheng <ycheng@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r--net/ipv4/tcp_input.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 5dfbc333e79a..6660ce2a7333 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -6263,6 +6263,11 @@ static inline void pr_drop_req(struct request_sock *req, __u16 port, int family)
6263 * congestion control: Linux DCTCP asserts ECT on all packets, 6263 * congestion control: Linux DCTCP asserts ECT on all packets,
6264 * including SYN, which is most optimal solution; however, 6264 * including SYN, which is most optimal solution; however,
6265 * others, such as FreeBSD do not. 6265 * others, such as FreeBSD do not.
6266 *
6267 * Exception: At least one of the reserved bits of the TCP header (th->res1) is
6268 * set, indicating the use of a future TCP extension (such as AccECN). See
6269 * RFC8311 §4.3 which updates RFC3168 to allow the development of such
6270 * extensions.
6266 */ 6271 */
6267static void tcp_ecn_create_request(struct request_sock *req, 6272static void tcp_ecn_create_request(struct request_sock *req,
6268 const struct sk_buff *skb, 6273 const struct sk_buff *skb,
@@ -6282,7 +6287,7 @@ static void tcp_ecn_create_request(struct request_sock *req,
6282 ecn_ok_dst = dst_feature(dst, DST_FEATURE_ECN_MASK); 6287 ecn_ok_dst = dst_feature(dst, DST_FEATURE_ECN_MASK);
6283 ecn_ok = net->ipv4.sysctl_tcp_ecn || ecn_ok_dst; 6288 ecn_ok = net->ipv4.sysctl_tcp_ecn || ecn_ok_dst;
6284 6289
6285 if ((!ect && ecn_ok) || tcp_ca_needs_ecn(listen_sk) || 6290 if (((!ect || th->res1) && ecn_ok) || tcp_ca_needs_ecn(listen_sk) ||
6286 (ecn_ok_dst & DST_FEATURE_ECN_CA) || 6291 (ecn_ok_dst & DST_FEATURE_ECN_CA) ||
6287 tcp_bpf_ca_needs_ecn((struct sock *)req)) 6292 tcp_bpf_ca_needs_ecn((struct sock *)req))
6288 inet_rsk(req)->ecn_ok = 1; 6293 inet_rsk(req)->ecn_ok = 1;