tcp_ecn.h 3.2 KB

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