xref: /linux/include/net/tcp_ecn.h (revision b5e74132dfbe60329b3ff0e5c485039f2e31605c)
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 #include <linux/bitfield.h>
8 
9 #include <net/inet_connection_sock.h>
10 #include <net/sock.h>
11 #include <net/tcp.h>
12 #include <net/inet_ecn.h>
13 
14 /* The highest ECN variant (Accurate ECN, ECN, or no ECN) that is
15  * attemped to be negotiated and requested for incoming connection
16  * and outgoing connection, respectively.
17  */
18 enum tcp_ecn_mode {
19 	TCP_ECN_IN_NOECN_OUT_NOECN = 0,
20 	TCP_ECN_IN_ECN_OUT_ECN = 1,
21 	TCP_ECN_IN_ECN_OUT_NOECN = 2,
22 	TCP_ECN_IN_ACCECN_OUT_ACCECN = 3,
23 	TCP_ECN_IN_ACCECN_OUT_ECN = 4,
24 	TCP_ECN_IN_ACCECN_OUT_NOECN = 5,
25 };
26 
27 /* AccECN option sending when AccECN has been successfully negotiated */
28 enum tcp_accecn_option {
29 	TCP_ACCECN_OPTION_DISABLED = 0,
30 	TCP_ACCECN_OPTION_MINIMUM = 1,
31 	TCP_ACCECN_OPTION_FULL = 2,
32 };
33 
34 static inline void tcp_ecn_queue_cwr(struct tcp_sock *tp)
35 {
36 	/* Do not set CWR if in AccECN mode! */
37 	if (tcp_ecn_mode_rfc3168(tp))
38 		tp->ecn_flags |= TCP_ECN_QUEUE_CWR;
39 }
40 
41 static inline void tcp_ecn_accept_cwr(struct sock *sk,
42 				      const struct sk_buff *skb)
43 {
44 	struct tcp_sock *tp = tcp_sk(sk);
45 
46 	if (tcp_ecn_mode_rfc3168(tp) && tcp_hdr(skb)->cwr) {
47 		tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR;
48 
49 		/* If the sender is telling us it has entered CWR, then its
50 		 * cwnd may be very low (even just 1 packet), so we should ACK
51 		 * immediately.
52 		 */
53 		if (TCP_SKB_CB(skb)->seq != TCP_SKB_CB(skb)->end_seq)
54 			inet_csk(sk)->icsk_ack.pending |= ICSK_ACK_NOW;
55 	}
56 }
57 
58 static inline void tcp_ecn_withdraw_cwr(struct tcp_sock *tp)
59 {
60 	tp->ecn_flags &= ~TCP_ECN_QUEUE_CWR;
61 }
62 
63 /* tp->accecn_fail_mode */
64 #define TCP_ACCECN_ACE_FAIL_SEND	BIT(0)
65 #define TCP_ACCECN_ACE_FAIL_RECV	BIT(1)
66 #define TCP_ACCECN_OPT_FAIL_SEND	BIT(2)
67 #define TCP_ACCECN_OPT_FAIL_RECV	BIT(3)
68 
69 static inline bool tcp_accecn_ace_fail_send(const struct tcp_sock *tp)
70 {
71 	return tp->accecn_fail_mode & TCP_ACCECN_ACE_FAIL_SEND;
72 }
73 
74 static inline bool tcp_accecn_ace_fail_recv(const struct tcp_sock *tp)
75 {
76 	return tp->accecn_fail_mode & TCP_ACCECN_ACE_FAIL_RECV;
77 }
78 
79 static inline bool tcp_accecn_opt_fail_send(const struct tcp_sock *tp)
80 {
81 	return tp->accecn_fail_mode & TCP_ACCECN_OPT_FAIL_SEND;
82 }
83 
84 static inline bool tcp_accecn_opt_fail_recv(const struct tcp_sock *tp)
85 {
86 	return tp->accecn_fail_mode & TCP_ACCECN_OPT_FAIL_RECV;
87 }
88 
89 static inline void tcp_accecn_fail_mode_set(struct tcp_sock *tp, u8 mode)
90 {
91 	tp->accecn_fail_mode |= mode;
92 }
93 
94 static inline u8 tcp_accecn_ace(const struct tcphdr *th)
95 {
96 	return (th->ae << 2) | (th->cwr << 1) | th->ece;
97 }
98 
99 /* Infer the ECT value our SYN arrived with from the echoed ACE field */
100 static inline int tcp_accecn_extract_syn_ect(u8 ace)
101 {
102 	/* Below is an excerpt from the 1st block of Table 2 of AccECN spec */
103 	static const int ace_to_ecn[8] = {
104 		INET_ECN_ECT_0,		/* 0b000 (Undefined) */
105 		INET_ECN_ECT_1,		/* 0b001 (Undefined) */
106 		INET_ECN_NOT_ECT,	/* 0b010 (Not-ECT is received) */
107 		INET_ECN_ECT_1,		/* 0b011 (ECT-1 is received) */
108 		INET_ECN_ECT_0,		/* 0b100 (ECT-0 is received) */
109 		INET_ECN_ECT_1,		/* 0b101 (Reserved) */
110 		INET_ECN_CE,		/* 0b110 (CE is received) */
111 		INET_ECN_ECT_1		/* 0b111 (Undefined) */
112 	};
113 
114 	return ace_to_ecn[ace & 0x7];
115 }
116 
117 /* Check ECN field transition to detect invalid transitions */
118 static inline bool tcp_ect_transition_valid(u8 snt, u8 rcv)
119 {
120 	if (rcv == snt)
121 		return true;
122 
123 	/* Non-ECT altered to something or something became non-ECT */
124 	if (snt == INET_ECN_NOT_ECT || rcv == INET_ECN_NOT_ECT)
125 		return false;
126 	/* CE -> ECT(0/1)? */
127 	if (snt == INET_ECN_CE)
128 		return false;
129 	return true;
130 }
131 
132 static inline bool tcp_accecn_validate_syn_feedback(struct sock *sk, u8 ace,
133 						    u8 sent_ect)
134 {
135 	u8 ect = tcp_accecn_extract_syn_ect(ace);
136 	struct tcp_sock *tp = tcp_sk(sk);
137 
138 	if (!READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_ecn_fallback))
139 		return true;
140 
141 	if (!tcp_ect_transition_valid(sent_ect, ect)) {
142 		tcp_accecn_fail_mode_set(tp, TCP_ACCECN_ACE_FAIL_RECV);
143 		return false;
144 	}
145 
146 	return true;
147 }
148 
149 /* Validate the 3rd ACK based on the ACE field, see Table 4 of AccECN spec */
150 static inline void tcp_accecn_third_ack(struct sock *sk,
151 					const struct sk_buff *skb, u8 sent_ect)
152 {
153 	u8 ace = tcp_accecn_ace(tcp_hdr(skb));
154 	struct tcp_sock *tp = tcp_sk(sk);
155 
156 	switch (ace) {
157 	case 0x0:
158 		/* Invalid value */
159 		tcp_accecn_fail_mode_set(tp, TCP_ACCECN_ACE_FAIL_RECV);
160 		break;
161 	case 0x7:
162 	case 0x5:
163 	case 0x1:
164 		/* Unused but legal values */
165 		break;
166 	default:
167 		/* Validation only applies to first non-data packet */
168 		if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq &&
169 		    !TCP_SKB_CB(skb)->sacked &&
170 		    tcp_accecn_validate_syn_feedback(sk, ace, sent_ect)) {
171 			if ((tcp_accecn_extract_syn_ect(ace) == INET_ECN_CE) &&
172 			    !tp->delivered_ce)
173 				tp->delivered_ce++;
174 		}
175 		break;
176 	}
177 }
178 
179 /* Maps IP ECN field ECT/CE code point to AccECN option field number, given
180  * we are sending fields with Accurate ECN Order 1: ECT(1), CE, ECT(0).
181  */
182 static inline u8 tcp_ecnfield_to_accecn_optfield(u8 ecnfield)
183 {
184 	switch (ecnfield & INET_ECN_MASK) {
185 	case INET_ECN_NOT_ECT:
186 		return 0;	/* AccECN does not send counts of NOT_ECT */
187 	case INET_ECN_ECT_1:
188 		return 1;
189 	case INET_ECN_CE:
190 		return 2;
191 	case INET_ECN_ECT_0:
192 		return 3;
193 	}
194 	return 0;
195 }
196 
197 /* Maps IP ECN field ECT/CE code point to AccECN option field value offset.
198  * Some fields do not start from zero, to detect zeroing by middleboxes.
199  */
200 static inline u32 tcp_accecn_field_init_offset(u8 ecnfield)
201 {
202 	switch (ecnfield & INET_ECN_MASK) {
203 	case INET_ECN_NOT_ECT:
204 		return 0;	/* AccECN does not send counts of NOT_ECT */
205 	case INET_ECN_ECT_1:
206 		return TCP_ACCECN_E1B_INIT_OFFSET;
207 	case INET_ECN_CE:
208 		return TCP_ACCECN_CEB_INIT_OFFSET;
209 	case INET_ECN_ECT_0:
210 		return TCP_ACCECN_E0B_INIT_OFFSET;
211 	}
212 	return 0;
213 }
214 
215 /* Maps AccECN option field #nr to IP ECN field ECT/CE bits */
216 static inline unsigned int tcp_accecn_optfield_to_ecnfield(unsigned int option,
217 							   bool order)
218 {
219 	/* Based on Table 5 of the AccECN spec to map (option, order) to
220 	 * the corresponding ECN conuters (ECT-1, ECT-0, or CE).
221 	 */
222 	static const u8 optfield_lookup[2][3] = {
223 		/* order = 0: 1st field ECT-0, 2nd field CE, 3rd field ECT-1 */
224 		{ INET_ECN_ECT_0, INET_ECN_CE, INET_ECN_ECT_1 },
225 		/* order = 1: 1st field ECT-1, 2nd field CE, 3rd field ECT-0 */
226 		{ INET_ECN_ECT_1, INET_ECN_CE, INET_ECN_ECT_0 }
227 	};
228 
229 	return optfield_lookup[order][option % 3];
230 }
231 
232 /* Handles AccECN option ECT and CE 24-bit byte counters update into
233  * the u32 value in tcp_sock. As we're processing TCP options, it is
234  * safe to access from - 1.
235  */
236 static inline s32 tcp_update_ecn_bytes(u32 *cnt, const char *from,
237 				       u32 init_offset)
238 {
239 	u32 truncated = (get_unaligned_be32(from - 1) - init_offset) &
240 			0xFFFFFFU;
241 	u32 delta = (truncated - *cnt) & 0xFFFFFFU;
242 
243 	/* If delta has the highest bit set (24th bit) indicating
244 	 * negative, sign extend to correct an estimation using
245 	 * sign_extend32(delta, 24 - 1)
246 	 */
247 	delta = sign_extend32(delta, 23);
248 	*cnt += delta;
249 	return (s32)delta;
250 }
251 
252 /* Updates Accurate ECN received counters from the received IP ECN field */
253 static inline void tcp_ecn_received_counters(struct sock *sk,
254 					     const struct sk_buff *skb, u32 len)
255 {
256 	u8 ecnfield = TCP_SKB_CB(skb)->ip_dsfield & INET_ECN_MASK;
257 	u8 is_ce = INET_ECN_is_ce(ecnfield);
258 	struct tcp_sock *tp = tcp_sk(sk);
259 
260 	if (!INET_ECN_is_not_ect(ecnfield)) {
261 		u32 pcount = is_ce * max_t(u16, 1, skb_shinfo(skb)->gso_segs);
262 
263 		/* As for accurate ECN, the TCP_ECN_SEEN flag is set by
264 		 * tcp_ecn_received_counters() when the ECN codepoint of
265 		 * received TCP data or ACK contains ECT(0), ECT(1), or CE.
266 		 */
267 		if (!tcp_ecn_mode_rfc3168(tp))
268 			tp->ecn_flags |= TCP_ECN_SEEN;
269 
270 		/* ACE counter tracks *all* segments including pure ACKs */
271 		tp->received_ce += pcount;
272 		tp->received_ce_pending = min(tp->received_ce_pending + pcount,
273 					      0xfU);
274 
275 		if (len > 0) {
276 			u8 minlen = tcp_ecnfield_to_accecn_optfield(ecnfield);
277 			tp->received_ecn_bytes[ecnfield - 1] += len;
278 			tp->accecn_minlen = max_t(u8, tp->accecn_minlen,
279 						  minlen);
280 		}
281 	}
282 }
283 
284 /* AccECN specification, 2.2: [...] A Data Receiver maintains four counters
285  * initialized at the start of	the half-connection. [...] These byte counters
286  * reflect only the TCP payload length, excluding TCP header and TCP options.
287  */
288 static inline void tcp_ecn_received_counters_payload(struct sock *sk,
289 						     const struct sk_buff *skb)
290 {
291 	const struct tcphdr *th = (const struct tcphdr *)skb->data;
292 
293 	tcp_ecn_received_counters(sk, skb, skb->len - th->doff * 4);
294 }
295 
296 /* AccECN specification, 5.1: [...] a server can determine that it
297  * negotiated AccECN as [...] if the ACK contains an ACE field with
298  * the value 0b010 to 0b111 (decimal 2 to 7).
299  */
300 static inline bool cookie_accecn_ok(const struct tcphdr *th)
301 {
302 	return tcp_accecn_ace(th) > 0x1;
303 }
304 
305 /* Used to form the ACE flags for SYN/ACK */
306 static inline u16 tcp_accecn_reflector_flags(u8 ect)
307 {
308 	/* TCP ACE flags of SYN/ACK are set based on IP-ECN received from SYN.
309 	 * Below is an excerpt from the 1st block of Table 2 of AccECN spec,
310 	 * in which TCP ACE flags are encoded as: (AE << 2) | (CWR << 1) | ECE
311 	 */
312 	static const u8 ecn_to_ace_flags[4] = {
313 		0b010,	/* Not-ECT is received */
314 		0b011,	/* ECT(1) is received */
315 		0b100,	/* ECT(0) is received */
316 		0b110	/* CE is received */
317 	};
318 
319 	return FIELD_PREP(TCPHDR_ACE, ecn_to_ace_flags[ect & 0x3]);
320 }
321 
322 /* AccECN specification, 3.1.2: If a TCP server that implements AccECN
323  * receives a SYN with the three TCP header flags (AE, CWR and ECE) set
324  * to any combination other than 000, 011 or 111, it MUST negotiate the
325  * use of AccECN as if they had been set to 111.
326  */
327 static inline bool tcp_accecn_syn_requested(const struct tcphdr *th)
328 {
329 	u8 ace = tcp_accecn_ace(th);
330 
331 	return ace && ace != 0x3;
332 }
333 
334 static inline void __tcp_accecn_init_bytes_counters(int *counter_array)
335 {
336 	BUILD_BUG_ON(INET_ECN_ECT_1 != 0x1);
337 	BUILD_BUG_ON(INET_ECN_ECT_0 != 0x2);
338 	BUILD_BUG_ON(INET_ECN_CE != 0x3);
339 
340 	counter_array[INET_ECN_ECT_1 - 1] = 0;
341 	counter_array[INET_ECN_ECT_0 - 1] = 0;
342 	counter_array[INET_ECN_CE - 1] = 0;
343 }
344 
345 static inline void tcp_accecn_init_counters(struct tcp_sock *tp)
346 {
347 	tp->received_ce = 0;
348 	tp->received_ce_pending = 0;
349 	__tcp_accecn_init_bytes_counters(tp->received_ecn_bytes);
350 	__tcp_accecn_init_bytes_counters(tp->delivered_ecn_bytes);
351 	tp->accecn_minlen = 0;
352 	tp->est_ecnfield = 0;
353 }
354 
355 /* Used for make_synack to form the ACE flags */
356 static inline void tcp_accecn_echo_syn_ect(struct tcphdr *th, u8 ect)
357 {
358 	/* TCP ACE flags of SYN/ACK are set based on IP-ECN codepoint received
359 	 * from SYN. Below is an excerpt from Table 2 of the AccECN spec:
360 	 * +====================+====================================+
361 	 * |  IP-ECN codepoint  |  Respective ACE falgs on SYN/ACK   |
362 	 * |   received on SYN  |       AE       CWR       ECE       |
363 	 * +====================+====================================+
364 	 * |      Not-ECT       |       0         1         0        |
365 	 * |      ECT(1)        |       0         1         1        |
366 	 * |      ECT(0)        |       1         0         0        |
367 	 * |        CE          |       1         1         0        |
368 	 * +====================+====================================+
369 	 */
370 	th->ae = !!(ect & INET_ECN_ECT_0);
371 	th->cwr = ect != INET_ECN_ECT_0;
372 	th->ece = ect == INET_ECN_ECT_1;
373 }
374 
375 static inline void tcp_accecn_set_ace(struct tcp_sock *tp, struct sk_buff *skb,
376 				      struct tcphdr *th)
377 {
378 	u32 wire_ace;
379 
380 	/* The final packet of the 3WHS or anything like it must reflect
381 	 * the SYN/ACK ECT instead of putting CEP into ACE field, such
382 	 * case show up in tcp_flags.
383 	 */
384 	if (likely(!(TCP_SKB_CB(skb)->tcp_flags & TCPHDR_ACE))) {
385 		wire_ace = tp->received_ce + TCP_ACCECN_CEP_INIT_OFFSET;
386 		th->ece = !!(wire_ace & 0x1);
387 		th->cwr = !!(wire_ace & 0x2);
388 		th->ae = !!(wire_ace & 0x4);
389 		tp->received_ce_pending = 0;
390 	}
391 }
392 
393 /* See Table 2 of the AccECN draft */
394 static inline void tcp_ecn_rcv_synack(struct sock *sk, const struct tcphdr *th,
395 				      u8 ip_dsfield)
396 {
397 	struct tcp_sock *tp = tcp_sk(sk);
398 	u8 ace = tcp_accecn_ace(th);
399 
400 	switch (ace) {
401 	case 0x0:
402 	case 0x7:
403 		/* +========+========+============+=============+
404 		 * | A      | B      |  SYN/ACK   |  Feedback   |
405 		 * |        |        |    B->A    |  Mode of A  |
406 		 * |        |        | AE CWR ECE |             |
407 		 * +========+========+============+=============+
408 		 * | AccECN | No ECN | 0   0   0  |   Not ECN   |
409 		 * | AccECN | Broken | 1   1   1  |   Not ECN   |
410 		 * +========+========+============+=============+
411 		 */
412 		tcp_ecn_mode_set(tp, TCP_ECN_DISABLED);
413 		break;
414 	case 0x1:
415 	case 0x5:
416 		/* +========+========+============+=============+
417 		 * | A      | B      |  SYN/ACK   |  Feedback   |
418 		 * |        |        |    B->A    |  Mode of A  |
419 		 * |        |        | AE CWR ECE |             |
420 		 * +========+========+============+=============+
421 		 * | AccECN | Nonce  | 1   0   1  | (Reserved)  |
422 		 * | AccECN | ECN    | 0   0   1  | Classic ECN |
423 		 * | Nonce  | AccECN | 0   0   1  | Classic ECN |
424 		 * | ECN    | AccECN | 0   0   1  | Classic ECN |
425 		 * +========+========+============+=============+
426 		 */
427 		if (tcp_ecn_mode_pending(tp))
428 			/* Downgrade from AccECN, or requested initially */
429 			tcp_ecn_mode_set(tp, TCP_ECN_MODE_RFC3168);
430 		break;
431 	default:
432 		tcp_ecn_mode_set(tp, TCP_ECN_MODE_ACCECN);
433 		tp->syn_ect_rcv = ip_dsfield & INET_ECN_MASK;
434 		if (INET_ECN_is_ce(ip_dsfield) &&
435 		    tcp_accecn_validate_syn_feedback(sk, ace,
436 						     tp->syn_ect_snt)) {
437 			tp->received_ce++;
438 			tp->received_ce_pending++;
439 		}
440 		break;
441 	}
442 }
443 
444 static inline void tcp_ecn_rcv_syn(struct tcp_sock *tp, const struct tcphdr *th,
445 				   const struct sk_buff *skb)
446 {
447 	if (tcp_ecn_mode_pending(tp)) {
448 		if (!tcp_accecn_syn_requested(th)) {
449 			/* Downgrade to classic ECN feedback */
450 			tcp_ecn_mode_set(tp, TCP_ECN_MODE_RFC3168);
451 		} else {
452 			tp->syn_ect_rcv = TCP_SKB_CB(skb)->ip_dsfield &
453 					  INET_ECN_MASK;
454 			tcp_ecn_mode_set(tp, TCP_ECN_MODE_ACCECN);
455 		}
456 	}
457 	if (tcp_ecn_mode_rfc3168(tp) && (!th->ece || !th->cwr))
458 		tcp_ecn_mode_set(tp, TCP_ECN_DISABLED);
459 }
460 
461 static inline bool tcp_ecn_rcv_ecn_echo(const struct tcp_sock *tp,
462 					const struct tcphdr *th)
463 {
464 	if (th->ece && !th->syn && tcp_ecn_mode_rfc3168(tp))
465 		return true;
466 	return false;
467 }
468 
469 /* Packet ECN state for a SYN-ACK */
470 static inline void tcp_ecn_send_synack(struct sock *sk, struct sk_buff *skb)
471 {
472 	struct tcp_sock *tp = tcp_sk(sk);
473 
474 	TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_CWR;
475 	if (tcp_ecn_disabled(tp))
476 		TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_ECE;
477 	else if (tcp_ca_needs_ecn(sk) ||
478 		 tcp_bpf_ca_needs_ecn(sk))
479 		INET_ECN_xmit(sk);
480 
481 	if (tp->ecn_flags & TCP_ECN_MODE_ACCECN) {
482 		TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_ACE;
483 		TCP_SKB_CB(skb)->tcp_flags |=
484 			tcp_accecn_reflector_flags(tp->syn_ect_rcv);
485 		tp->syn_ect_snt = inet_sk(sk)->tos & INET_ECN_MASK;
486 	}
487 }
488 
489 /* Packet ECN state for a SYN.  */
490 static inline void tcp_ecn_send_syn(struct sock *sk, struct sk_buff *skb)
491 {
492 	struct tcp_sock *tp = tcp_sk(sk);
493 	bool bpf_needs_ecn = tcp_bpf_ca_needs_ecn(sk);
494 	bool use_ecn, use_accecn;
495 	u8 tcp_ecn = READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_ecn);
496 
497 	use_accecn = tcp_ecn == TCP_ECN_IN_ACCECN_OUT_ACCECN;
498 	use_ecn = tcp_ecn == TCP_ECN_IN_ECN_OUT_ECN ||
499 		  tcp_ecn == TCP_ECN_IN_ACCECN_OUT_ECN ||
500 		  tcp_ca_needs_ecn(sk) || bpf_needs_ecn || use_accecn;
501 
502 	if (!use_ecn) {
503 		const struct dst_entry *dst = __sk_dst_get(sk);
504 
505 		if (dst && dst_feature(dst, RTAX_FEATURE_ECN))
506 			use_ecn = true;
507 	}
508 
509 	tp->ecn_flags = 0;
510 
511 	if (use_ecn) {
512 		if (tcp_ca_needs_ecn(sk) || bpf_needs_ecn)
513 			INET_ECN_xmit(sk);
514 
515 		TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_ECE | TCPHDR_CWR;
516 		if (use_accecn) {
517 			TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_AE;
518 			tcp_ecn_mode_set(tp, TCP_ECN_MODE_PENDING);
519 			tp->syn_ect_snt = inet_sk(sk)->tos & INET_ECN_MASK;
520 		} else {
521 			tcp_ecn_mode_set(tp, TCP_ECN_MODE_RFC3168);
522 		}
523 	}
524 }
525 
526 static inline void tcp_ecn_clear_syn(struct sock *sk, struct sk_buff *skb)
527 {
528 	if (READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_ecn_fallback)) {
529 		/* tp->ecn_flags are cleared at a later point in time when
530 		 * SYN ACK is ultimatively being received.
531 		 */
532 		TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_ACE;
533 	}
534 }
535 
536 static inline void
537 tcp_ecn_make_synack(const struct request_sock *req, struct tcphdr *th)
538 {
539 	if (tcp_rsk(req)->accecn_ok)
540 		tcp_accecn_echo_syn_ect(th, tcp_rsk(req)->syn_ect_rcv);
541 	else if (inet_rsk(req)->ecn_ok)
542 		th->ece = 1;
543 }
544 
545 #endif /* _LINUX_TCP_ECN_H */
546