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