tcp_ecn.h 3.2 KB

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