1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 #ifndef _TCP_ECN_H 3 #define _TCP_ECN_H 4 5 #include <linux/tcp.h> 6 #include <linux/skbuff.h> 7 8 #include <net/inet_connection_sock.h> 9 #include <net/sock.h> 10 #include <net/tcp.h> 11 #include <net/inet_ecn.h> 12 13 static inline void tcp_ecn_queue_cwr(struct tcp_sock *tp) 14 { 15 /* Do not set CWR if in AccECN mode! */ 16 if (tcp_ecn_mode_rfc3168(tp)) 17 tp->ecn_flags |= TCP_ECN_QUEUE_CWR; 18 } 19 20 static inline void tcp_ecn_accept_cwr(struct sock *sk, 21 const struct sk_buff *skb) 22 { 23 struct tcp_sock *tp = tcp_sk(sk); 24 25 if (tcp_ecn_mode_rfc3168(tp) && tcp_hdr(skb)->cwr) { 26 tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR; 27 28 /* If the sender is telling us it has entered CWR, then its 29 * cwnd may be very low (even just 1 packet), so we should ACK 30 * immediately. 31 */ 32 if (TCP_SKB_CB(skb)->seq != TCP_SKB_CB(skb)->end_seq) 33 inet_csk(sk)->icsk_ack.pending |= ICSK_ACK_NOW; 34 } 35 } 36 37 static inline void tcp_ecn_withdraw_cwr(struct tcp_sock *tp) 38 { 39 tp->ecn_flags &= ~TCP_ECN_QUEUE_CWR; 40 } 41 42 static inline u8 tcp_accecn_ace(const struct tcphdr *th) 43 { 44 return (th->ae << 2) | (th->cwr << 1) | th->ece; 45 } 46 47 static inline void tcp_accecn_init_counters(struct tcp_sock *tp) 48 { 49 tp->received_ce = 0; 50 tp->received_ce_pending = 0; 51 } 52 53 /* Updates Accurate ECN received counters from the received IP ECN field */ 54 static inline void tcp_ecn_received_counters(struct sock *sk, const struct sk_buff *skb) 55 { 56 u8 ecnfield = TCP_SKB_CB(skb)->ip_dsfield & INET_ECN_MASK; 57 u8 is_ce = INET_ECN_is_ce(ecnfield); 58 struct tcp_sock *tp = tcp_sk(sk); 59 60 if (!INET_ECN_is_not_ect(ecnfield)) { 61 u32 pcount = is_ce * max_t(u16, 1, skb_shinfo(skb)->gso_segs); 62 63 /* As for accurate ECN, the TCP_ECN_SEEN flag is set by 64 * tcp_ecn_received_counters() when the ECN codepoint of 65 * received TCP data or ACK contains ECT(0), ECT(1), or CE. 66 */ 67 if (!tcp_ecn_mode_rfc3168(tp)) 68 tp->ecn_flags |= TCP_ECN_SEEN; 69 70 /* ACE counter tracks *all* segments including pure ACKs */ 71 tp->received_ce += pcount; 72 tp->received_ce_pending = min(tp->received_ce_pending + pcount, 73 0xfU); 74 } 75 } 76 77 static inline void tcp_accecn_set_ace(struct tcphdr *th, struct tcp_sock *tp) 78 { 79 u32 wire_ace; 80 81 wire_ace = tp->received_ce + TCP_ACCECN_CEP_INIT_OFFSET; 82 th->ece = !!(wire_ace & 0x1); 83 th->cwr = !!(wire_ace & 0x2); 84 th->ae = !!(wire_ace & 0x4); 85 tp->received_ce_pending = 0; 86 } 87 88 static inline void tcp_ecn_rcv_synack(struct tcp_sock *tp, 89 const struct tcphdr *th) 90 { 91 if (tcp_ecn_mode_rfc3168(tp) && (!th->ece || th->cwr)) 92 tcp_ecn_mode_set(tp, TCP_ECN_DISABLED); 93 } 94 95 static inline void tcp_ecn_rcv_syn(struct tcp_sock *tp, 96 const struct tcphdr *th) 97 { 98 if (tcp_ecn_mode_rfc3168(tp) && (!th->ece || !th->cwr)) 99 tcp_ecn_mode_set(tp, TCP_ECN_DISABLED); 100 } 101 102 static inline bool tcp_ecn_rcv_ecn_echo(const struct tcp_sock *tp, 103 const struct tcphdr *th) 104 { 105 if (th->ece && !th->syn && tcp_ecn_mode_rfc3168(tp)) 106 return true; 107 return false; 108 } 109 110 /* Packet ECN state for a SYN-ACK */ 111 static inline void tcp_ecn_send_synack(struct sock *sk, struct sk_buff *skb) 112 { 113 const struct tcp_sock *tp = tcp_sk(sk); 114 115 TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_CWR; 116 if (tcp_ecn_disabled(tp)) 117 TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_ECE; 118 else if (tcp_ca_needs_ecn(sk) || 119 tcp_bpf_ca_needs_ecn(sk)) 120 INET_ECN_xmit(sk); 121 } 122 123 /* Packet ECN state for a SYN. */ 124 static inline void tcp_ecn_send_syn(struct sock *sk, struct sk_buff *skb) 125 { 126 struct tcp_sock *tp = tcp_sk(sk); 127 bool bpf_needs_ecn = tcp_bpf_ca_needs_ecn(sk); 128 bool use_ecn = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_ecn) == 1 || 129 tcp_ca_needs_ecn(sk) || bpf_needs_ecn; 130 131 if (!use_ecn) { 132 const struct dst_entry *dst = __sk_dst_get(sk); 133 134 if (dst && dst_feature(dst, RTAX_FEATURE_ECN)) 135 use_ecn = true; 136 } 137 138 tp->ecn_flags = 0; 139 140 if (use_ecn) { 141 if (tcp_ca_needs_ecn(sk) || bpf_needs_ecn) 142 INET_ECN_xmit(sk); 143 144 TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_ECE | TCPHDR_CWR; 145 tcp_ecn_mode_set(tp, TCP_ECN_MODE_RFC3168); 146 } 147 } 148 149 static inline void tcp_ecn_clear_syn(struct sock *sk, struct sk_buff *skb) 150 { 151 if (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_ecn_fallback)) 152 /* tp->ecn_flags are cleared at a later point in time when 153 * SYN ACK is ultimatively being received. 154 */ 155 TCP_SKB_CB(skb)->tcp_flags &= ~(TCPHDR_ECE | TCPHDR_CWR); 156 } 157 158 static inline void 159 tcp_ecn_make_synack(const struct request_sock *req, struct tcphdr *th) 160 { 161 if (inet_rsk(req)->ecn_ok) 162 th->ece = 1; 163 } 164 165 #endif /* _LINUX_TCP_ECN_H */ 166