tcp_ecn.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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 tcp_sock *tp,
  23. struct sk_buff *skb)
  24. {
  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 tcp_sock *tp,
  38. struct sk_buff *skb, int tcp_header_len)
  39. {
  40. if (tp->ecn_flags & TCP_ECN_OK) {
  41. /* Not-retransmitted data segment: set ECT and inject CWR. */
  42. if (skb->len != tcp_header_len &&
  43. !before(TCP_SKB_CB(skb)->seq, tp->snd_nxt)) {
  44. INET_ECN_xmit(sk);
  45. if (tp->ecn_flags&TCP_ECN_QUEUE_CWR) {
  46. tp->ecn_flags &= ~TCP_ECN_QUEUE_CWR;
  47. skb->h.th->cwr = 1;
  48. skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_ECN;
  49. }
  50. } else {
  51. /* ACK or retransmitted segment: clear ECT|CE */
  52. INET_ECN_dontxmit(sk);
  53. }
  54. if (tp->ecn_flags & TCP_ECN_DEMAND_CWR)
  55. skb->h.th->ece = 1;
  56. }
  57. }
  58. /* Input functions */
  59. static inline void TCP_ECN_accept_cwr(struct tcp_sock *tp, struct sk_buff *skb)
  60. {
  61. if (skb->h.th->cwr)
  62. tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR;
  63. }
  64. static inline void TCP_ECN_withdraw_cwr(struct tcp_sock *tp)
  65. {
  66. tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR;
  67. }
  68. static inline void TCP_ECN_check_ce(struct tcp_sock *tp, struct sk_buff *skb)
  69. {
  70. if (tp->ecn_flags&TCP_ECN_OK) {
  71. if (INET_ECN_is_ce(TCP_SKB_CB(skb)->flags))
  72. tp->ecn_flags |= TCP_ECN_DEMAND_CWR;
  73. /* Funny extension: if ECT is not set on a segment,
  74. * it is surely retransmit. It is not in ECN RFC,
  75. * but Linux follows this rule. */
  76. else if (INET_ECN_is_not_ect((TCP_SKB_CB(skb)->flags)))
  77. tcp_enter_quickack_mode((struct sock *)tp);
  78. }
  79. }
  80. static inline void TCP_ECN_rcv_synack(struct tcp_sock *tp, struct tcphdr *th)
  81. {
  82. if ((tp->ecn_flags&TCP_ECN_OK) && (!th->ece || th->cwr))
  83. tp->ecn_flags &= ~TCP_ECN_OK;
  84. }
  85. static inline void TCP_ECN_rcv_syn(struct tcp_sock *tp, struct tcphdr *th)
  86. {
  87. if ((tp->ecn_flags&TCP_ECN_OK) && (!th->ece || !th->cwr))
  88. tp->ecn_flags &= ~TCP_ECN_OK;
  89. }
  90. static inline int TCP_ECN_rcv_ecn_echo(struct tcp_sock *tp, struct tcphdr *th)
  91. {
  92. if (th->ece && !th->syn && (tp->ecn_flags&TCP_ECN_OK))
  93. return 1;
  94. return 0;
  95. }
  96. static inline void TCP_ECN_openreq_child(struct tcp_sock *tp,
  97. struct request_sock *req)
  98. {
  99. tp->ecn_flags = inet_rsk(req)->ecn_ok ? TCP_ECN_OK : 0;
  100. }
  101. static __inline__ void
  102. TCP_ECN_create_request(struct request_sock *req, struct tcphdr *th)
  103. {
  104. if (sysctl_tcp_ecn && th->ece && th->cwr)
  105. inet_rsk(req)->ecn_ok = 1;
  106. }
  107. #endif