162306a36Sopenharmony_ci#ifndef _TCP_DCTCP_H 262306a36Sopenharmony_ci#define _TCP_DCTCP_H 362306a36Sopenharmony_ci 462306a36Sopenharmony_cistatic inline void dctcp_ece_ack_cwr(struct sock *sk, u32 ce_state) 562306a36Sopenharmony_ci{ 662306a36Sopenharmony_ci struct tcp_sock *tp = tcp_sk(sk); 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci if (ce_state == 1) 962306a36Sopenharmony_ci tp->ecn_flags |= TCP_ECN_DEMAND_CWR; 1062306a36Sopenharmony_ci else 1162306a36Sopenharmony_ci tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR; 1262306a36Sopenharmony_ci} 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci/* Minimal DCTP CE state machine: 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci * S: 0 <- last pkt was non-CE 1762306a36Sopenharmony_ci * 1 <- last pkt was CE 1862306a36Sopenharmony_ci */ 1962306a36Sopenharmony_cistatic inline void dctcp_ece_ack_update(struct sock *sk, enum tcp_ca_event evt, 2062306a36Sopenharmony_ci u32 *prior_rcv_nxt, u32 *ce_state) 2162306a36Sopenharmony_ci{ 2262306a36Sopenharmony_ci u32 new_ce_state = (evt == CA_EVENT_ECN_IS_CE) ? 1 : 0; 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci if (*ce_state != new_ce_state) { 2562306a36Sopenharmony_ci /* CE state has changed, force an immediate ACK to 2662306a36Sopenharmony_ci * reflect the new CE state. If an ACK was delayed, 2762306a36Sopenharmony_ci * send that first to reflect the prior CE state. 2862306a36Sopenharmony_ci */ 2962306a36Sopenharmony_ci if (inet_csk(sk)->icsk_ack.pending & ICSK_ACK_TIMER) { 3062306a36Sopenharmony_ci dctcp_ece_ack_cwr(sk, *ce_state); 3162306a36Sopenharmony_ci __tcp_send_ack(sk, *prior_rcv_nxt); 3262306a36Sopenharmony_ci } 3362306a36Sopenharmony_ci inet_csk(sk)->icsk_ack.pending |= ICSK_ACK_NOW; 3462306a36Sopenharmony_ci } 3562306a36Sopenharmony_ci *prior_rcv_nxt = tcp_sk(sk)->rcv_nxt; 3662306a36Sopenharmony_ci *ce_state = new_ce_state; 3762306a36Sopenharmony_ci dctcp_ece_ack_cwr(sk, new_ce_state); 3862306a36Sopenharmony_ci} 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci#endif 41