Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tcp: helpers for ECN mode handling

Create helpers for TCP ECN modes. No functional changes.

Signed-off-by: Ilpo Järvinen <ij@kernel.org>
Signed-off-by: Chia-Yu Chang <chia-yu.chang@nokia-bell-labs.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Ilpo Järvinen and committed by
David S. Miller
041fb11d f0db2bca

+55 -17
+40 -4
include/net/tcp.h
··· 374 374 } 375 375 } 376 376 377 - #define TCP_ECN_OK 1 378 - #define TCP_ECN_QUEUE_CWR 2 379 - #define TCP_ECN_DEMAND_CWR 4 380 - #define TCP_ECN_SEEN 8 377 + #define TCP_ECN_MODE_RFC3168 BIT(0) 378 + #define TCP_ECN_QUEUE_CWR BIT(1) 379 + #define TCP_ECN_DEMAND_CWR BIT(2) 380 + #define TCP_ECN_SEEN BIT(3) 381 + #define TCP_ECN_MODE_ACCECN BIT(4) 382 + 383 + #define TCP_ECN_DISABLED 0 384 + #define TCP_ECN_MODE_PENDING (TCP_ECN_MODE_RFC3168 | TCP_ECN_MODE_ACCECN) 385 + #define TCP_ECN_MODE_ANY (TCP_ECN_MODE_RFC3168 | TCP_ECN_MODE_ACCECN) 386 + 387 + static inline bool tcp_ecn_mode_any(const struct tcp_sock *tp) 388 + { 389 + return tp->ecn_flags & TCP_ECN_MODE_ANY; 390 + } 391 + 392 + static inline bool tcp_ecn_mode_rfc3168(const struct tcp_sock *tp) 393 + { 394 + return (tp->ecn_flags & TCP_ECN_MODE_ANY) == TCP_ECN_MODE_RFC3168; 395 + } 396 + 397 + static inline bool tcp_ecn_mode_accecn(const struct tcp_sock *tp) 398 + { 399 + return (tp->ecn_flags & TCP_ECN_MODE_ANY) == TCP_ECN_MODE_ACCECN; 400 + } 401 + 402 + static inline bool tcp_ecn_disabled(const struct tcp_sock *tp) 403 + { 404 + return !tcp_ecn_mode_any(tp); 405 + } 406 + 407 + static inline bool tcp_ecn_mode_pending(const struct tcp_sock *tp) 408 + { 409 + return (tp->ecn_flags & TCP_ECN_MODE_PENDING) == TCP_ECN_MODE_PENDING; 410 + } 411 + 412 + static inline void tcp_ecn_mode_set(struct tcp_sock *tp, u8 mode) 413 + { 414 + tp->ecn_flags &= ~TCP_ECN_MODE_ANY; 415 + tp->ecn_flags |= mode; 416 + } 381 417 382 418 enum tcp_tw_status { 383 419 TCP_TW_SUCCESS = 0,
+1 -1
net/ipv4/tcp.c
··· 4138 4138 info->tcpi_rcv_wscale = tp->rx_opt.rcv_wscale; 4139 4139 } 4140 4140 4141 - if (tp->ecn_flags & TCP_ECN_OK) 4141 + if (tcp_ecn_mode_any(tp)) 4142 4142 info->tcpi_options |= TCPI_OPT_ECN; 4143 4143 if (tp->ecn_flags & TCP_ECN_SEEN) 4144 4144 info->tcpi_options |= TCPI_OPT_ECN_SEEN;
+1 -1
net/ipv4/tcp_dctcp.c
··· 90 90 { 91 91 const struct tcp_sock *tp = tcp_sk(sk); 92 92 93 - if ((tp->ecn_flags & TCP_ECN_OK) || 93 + if (tcp_ecn_mode_any(tp) || 94 94 (sk->sk_state == TCP_LISTEN || 95 95 sk->sk_state == TCP_CLOSE)) { 96 96 struct dctcp *ca = inet_csk_ca(sk);
+7 -7
net/ipv4/tcp_input.c
··· 342 342 343 343 static void tcp_ecn_queue_cwr(struct tcp_sock *tp) 344 344 { 345 - if (tp->ecn_flags & TCP_ECN_OK) 345 + if (tcp_ecn_mode_rfc3168(tp)) 346 346 tp->ecn_flags |= TCP_ECN_QUEUE_CWR; 347 347 } 348 348 ··· 369 369 { 370 370 struct tcp_sock *tp = tcp_sk(sk); 371 371 372 - if (!(tcp_sk(sk)->ecn_flags & TCP_ECN_OK)) 372 + if (tcp_ecn_disabled(tp)) 373 373 return; 374 374 375 375 switch (TCP_SKB_CB(skb)->ip_dsfield & INET_ECN_MASK) { ··· 402 402 403 403 static void tcp_ecn_rcv_synack(struct tcp_sock *tp, const struct tcphdr *th) 404 404 { 405 - if ((tp->ecn_flags & TCP_ECN_OK) && (!th->ece || th->cwr)) 406 - tp->ecn_flags &= ~TCP_ECN_OK; 405 + if (tcp_ecn_mode_rfc3168(tp) && (!th->ece || th->cwr)) 406 + tcp_ecn_mode_set(tp, TCP_ECN_DISABLED); 407 407 } 408 408 409 409 static void tcp_ecn_rcv_syn(struct tcp_sock *tp, const struct tcphdr *th) 410 410 { 411 - if ((tp->ecn_flags & TCP_ECN_OK) && (!th->ece || !th->cwr)) 412 - tp->ecn_flags &= ~TCP_ECN_OK; 411 + if (tcp_ecn_mode_rfc3168(tp) && (!th->ece || !th->cwr)) 412 + tcp_ecn_mode_set(tp, TCP_ECN_DISABLED); 413 413 } 414 414 415 415 static bool tcp_ecn_rcv_ecn_echo(const struct tcp_sock *tp, const struct tcphdr *th) 416 416 { 417 - if (th->ece && !th->syn && (tp->ecn_flags & TCP_ECN_OK)) 417 + if (th->ece && !th->syn && tcp_ecn_mode_rfc3168(tp)) 418 418 return true; 419 419 return false; 420 420 }
+3 -1
net/ipv4/tcp_minisocks.c
··· 461 461 static void tcp_ecn_openreq_child(struct tcp_sock *tp, 462 462 const struct request_sock *req) 463 463 { 464 - tp->ecn_flags = inet_rsk(req)->ecn_ok ? TCP_ECN_OK : 0; 464 + tcp_ecn_mode_set(tp, inet_rsk(req)->ecn_ok ? 465 + TCP_ECN_MODE_RFC3168 : 466 + TCP_ECN_DISABLED); 465 467 } 466 468 467 469 void tcp_ca_openreq_child(struct sock *sk, const struct dst_entry *dst)
+3 -3
net/ipv4/tcp_output.c
··· 325 325 const struct tcp_sock *tp = tcp_sk(sk); 326 326 327 327 TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_CWR; 328 - if (!(tp->ecn_flags & TCP_ECN_OK)) 328 + if (tcp_ecn_disabled(tp)) 329 329 TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_ECE; 330 330 else if (tcp_ca_needs_ecn(sk) || 331 331 tcp_bpf_ca_needs_ecn(sk)) ··· 351 351 352 352 if (use_ecn) { 353 353 TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_ECE | TCPHDR_CWR; 354 - tp->ecn_flags = TCP_ECN_OK; 354 + tcp_ecn_mode_set(tp, TCP_ECN_MODE_RFC3168); 355 355 if (tcp_ca_needs_ecn(sk) || bpf_needs_ecn) 356 356 INET_ECN_xmit(sk); 357 357 } ··· 381 381 { 382 382 struct tcp_sock *tp = tcp_sk(sk); 383 383 384 - if (tp->ecn_flags & TCP_ECN_OK) { 384 + if (tcp_ecn_mode_rfc3168(tp)) { 385 385 /* Not-retransmitted data segment: set ECT and inject CWR. */ 386 386 if (skb->len != tcp_header_len && 387 387 !before(TCP_SKB_CB(skb)->seq, tp->snd_nxt)) {