1 #ifndef _NET_TCP_ECN_H_ 2 #define _NET_TCP_ECN_H_ 1 3 4 #include <net/inet_ecn.h> 5 #include <net/request_sock.h> 6 7 #define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH)) 8 9 #define TCP_ECN_OK 1 10 #define TCP_ECN_QUEUE_CWR 2 11 #define TCP_ECN_DEMAND_CWR 4 12 13 static inline void TCP_ECN_queue_cwr(struct tcp_sock *tp) 14 { 15 if (tp->ecn_flags&TCP_ECN_OK) 16 tp->ecn_flags |= TCP_ECN_QUEUE_CWR; 17 } 18 19 20 /* Output functions */ 21 22 static inline void TCP_ECN_send_synack(struct tcp_sock *tp, 23 struct sk_buff *skb) 24 { 25 TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_CWR; 26 if (!(tp->ecn_flags&TCP_ECN_OK)) 27 TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_ECE; 28 } 29 30 static inline void TCP_ECN_send_syn(struct sock *sk, struct sk_buff *skb) 31 { 32 struct tcp_sock *tp = tcp_sk(sk); 33 34 tp->ecn_flags = 0; 35 if (sysctl_tcp_ecn) { 36 TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_ECE|TCPCB_FLAG_CWR; 37 tp->ecn_flags = TCP_ECN_OK; 38 } 39 } 40 41 static __inline__ void 42 TCP_ECN_make_synack(struct request_sock *req, struct tcphdr *th) 43 { 44 if (inet_rsk(req)->ecn_ok) 45 th->ece = 1; 46 } 47 48 static inline void TCP_ECN_send(struct sock *sk, struct sk_buff *skb, 49 int tcp_header_len) 50 { 51 struct tcp_sock *tp = tcp_sk(sk); 52 53 if (tp->ecn_flags & TCP_ECN_OK) { 54 /* Not-retransmitted data segment: set ECT and inject CWR. */ 55 if (skb->len != tcp_header_len && 56 !before(TCP_SKB_CB(skb)->seq, tp->snd_nxt)) { 57 INET_ECN_xmit(sk); 58 if (tp->ecn_flags&TCP_ECN_QUEUE_CWR) { 59 tp->ecn_flags &= ~TCP_ECN_QUEUE_CWR; 60 tcp_hdr(skb)->cwr = 1; 61 skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_ECN; 62 } 63 } else { 64 /* ACK or retransmitted segment: clear ECT|CE */ 65 INET_ECN_dontxmit(sk); 66 } 67 if (tp->ecn_flags & TCP_ECN_DEMAND_CWR) 68 tcp_hdr(skb)->ece = 1; 69 } 70 } 71 72 /* Input functions */ 73 74 static inline void TCP_ECN_accept_cwr(struct tcp_sock *tp, struct sk_buff *skb) 75 { 76 if (tcp_hdr(skb)->cwr) 77 tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR; 78 } 79 80 static inline void TCP_ECN_withdraw_cwr(struct tcp_sock *tp) 81 { 82 tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR; 83 } 84 85 static inline void TCP_ECN_check_ce(struct tcp_sock *tp, struct sk_buff *skb) 86 { 87 if (tp->ecn_flags&TCP_ECN_OK) { 88 if (INET_ECN_is_ce(TCP_SKB_CB(skb)->flags)) 89 tp->ecn_flags |= TCP_ECN_DEMAND_CWR; 90 /* Funny extension: if ECT is not set on a segment, 91 * it is surely retransmit. It is not in ECN RFC, 92 * but Linux follows this rule. */ 93 else if (INET_ECN_is_not_ect((TCP_SKB_CB(skb)->flags))) 94 tcp_enter_quickack_mode((struct sock *)tp); 95 } 96 } 97 98 static inline void TCP_ECN_rcv_synack(struct tcp_sock *tp, struct tcphdr *th) 99 { 100 if ((tp->ecn_flags&TCP_ECN_OK) && (!th->ece || th->cwr)) 101 tp->ecn_flags &= ~TCP_ECN_OK; 102 } 103 104 static inline void TCP_ECN_rcv_syn(struct tcp_sock *tp, struct tcphdr *th) 105 { 106 if ((tp->ecn_flags&TCP_ECN_OK) && (!th->ece || !th->cwr)) 107 tp->ecn_flags &= ~TCP_ECN_OK; 108 } 109 110 static inline int TCP_ECN_rcv_ecn_echo(struct tcp_sock *tp, struct tcphdr *th) 111 { 112 if (th->ece && !th->syn && (tp->ecn_flags&TCP_ECN_OK)) 113 return 1; 114 return 0; 115 } 116 117 static inline void TCP_ECN_openreq_child(struct tcp_sock *tp, 118 struct request_sock *req) 119 { 120 tp->ecn_flags = inet_rsk(req)->ecn_ok ? TCP_ECN_OK : 0; 121 } 122 123 static __inline__ void 124 TCP_ECN_create_request(struct request_sock *req, struct tcphdr *th) 125 { 126 if (sysctl_tcp_ecn && th->ece && th->cwr) 127 inet_rsk(req)->ecn_ok = 1; 128 } 129 130 #endif 131