1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _TCP_DCTCP_H 3 #define _TCP_DCTCP_H 4 5 static inline void dctcp_ece_ack_cwr(struct sock *sk, u32 ce_state) 6 { 7 struct tcp_sock *tp = tcp_sk(sk); 8 9 if (ce_state == 1) 10 tp->ecn_flags |= TCP_ECN_DEMAND_CWR; 11 else 12 tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR; 13 } 14 15 /* Minimal DCTP CE state machine: 16 * 17 * S: 0 <- last pkt was non-CE 18 * 1 <- last pkt was CE 19 */ 20 static inline void dctcp_ece_ack_update(struct sock *sk, enum tcp_ca_event evt, 21 u32 *prior_rcv_nxt, u32 *ce_state) 22 { 23 u32 new_ce_state = (evt == CA_EVENT_ECN_IS_CE) ? 1 : 0; 24 25 if (*ce_state != new_ce_state) { 26 /* CE state has changed, force an immediate ACK to 27 * reflect the new CE state. If an ACK was delayed, 28 * send that first to reflect the prior CE state. 29 */ 30 if (inet_csk(sk)->icsk_ack.pending & ICSK_ACK_TIMER) { 31 dctcp_ece_ack_cwr(sk, *ce_state); 32 __tcp_send_ack(sk, *prior_rcv_nxt, 0); 33 } 34 inet_csk(sk)->icsk_ack.pending |= ICSK_ACK_NOW; 35 } 36 *prior_rcv_nxt = tcp_sk(sk)->rcv_nxt; 37 *ce_state = new_ce_state; 38 dctcp_ece_ack_cwr(sk, new_ce_state); 39 } 40 41 #endif 42