diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /include/net/tcp_ecn.h |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'include/net/tcp_ecn.h')
-rw-r--r-- | include/net/tcp_ecn.h | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/include/net/tcp_ecn.h b/include/net/tcp_ecn.h new file mode 100644 index 000000000000..dc1456389a97 --- /dev/null +++ b/include/net/tcp_ecn.h | |||
@@ -0,0 +1,126 @@ | |||
1 | #ifndef _NET_TCP_ECN_H_ | ||
2 | #define _NET_TCP_ECN_H_ 1 | ||
3 | |||
4 | #include <net/inet_ecn.h> | ||
5 | |||
6 | #define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH)) | ||
7 | |||
8 | #define TCP_ECN_OK 1 | ||
9 | #define TCP_ECN_QUEUE_CWR 2 | ||
10 | #define TCP_ECN_DEMAND_CWR 4 | ||
11 | |||
12 | static inline void TCP_ECN_queue_cwr(struct tcp_sock *tp) | ||
13 | { | ||
14 | if (tp->ecn_flags&TCP_ECN_OK) | ||
15 | tp->ecn_flags |= TCP_ECN_QUEUE_CWR; | ||
16 | } | ||
17 | |||
18 | |||
19 | /* Output functions */ | ||
20 | |||
21 | static inline void TCP_ECN_send_synack(struct tcp_sock *tp, | ||
22 | struct sk_buff *skb) | ||
23 | { | ||
24 | TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_CWR; | ||
25 | if (!(tp->ecn_flags&TCP_ECN_OK)) | ||
26 | TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_ECE; | ||
27 | } | ||
28 | |||
29 | static inline void TCP_ECN_send_syn(struct sock *sk, struct tcp_sock *tp, | ||
30 | struct sk_buff *skb) | ||
31 | { | ||
32 | tp->ecn_flags = 0; | ||
33 | if (sysctl_tcp_ecn && !(sk->sk_route_caps & NETIF_F_TSO)) { | ||
34 | TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_ECE|TCPCB_FLAG_CWR; | ||
35 | tp->ecn_flags = TCP_ECN_OK; | ||
36 | sock_set_flag(sk, SOCK_NO_LARGESEND); | ||
37 | } | ||
38 | } | ||
39 | |||
40 | static __inline__ void | ||
41 | TCP_ECN_make_synack(struct open_request *req, struct tcphdr *th) | ||
42 | { | ||
43 | if (req->ecn_ok) | ||
44 | th->ece = 1; | ||
45 | } | ||
46 | |||
47 | static inline void TCP_ECN_send(struct sock *sk, struct tcp_sock *tp, | ||
48 | struct sk_buff *skb, int tcp_header_len) | ||
49 | { | ||
50 | if (tp->ecn_flags & TCP_ECN_OK) { | ||
51 | /* Not-retransmitted data segment: set ECT and inject CWR. */ | ||
52 | if (skb->len != tcp_header_len && | ||
53 | !before(TCP_SKB_CB(skb)->seq, tp->snd_nxt)) { | ||
54 | INET_ECN_xmit(sk); | ||
55 | if (tp->ecn_flags&TCP_ECN_QUEUE_CWR) { | ||
56 | tp->ecn_flags &= ~TCP_ECN_QUEUE_CWR; | ||
57 | skb->h.th->cwr = 1; | ||
58 | } | ||
59 | } else { | ||
60 | /* ACK or retransmitted segment: clear ECT|CE */ | ||
61 | INET_ECN_dontxmit(sk); | ||
62 | } | ||
63 | if (tp->ecn_flags & TCP_ECN_DEMAND_CWR) | ||
64 | skb->h.th->ece = 1; | ||
65 | } | ||
66 | } | ||
67 | |||
68 | /* Input functions */ | ||
69 | |||
70 | static inline void TCP_ECN_accept_cwr(struct tcp_sock *tp, struct sk_buff *skb) | ||
71 | { | ||
72 | if (skb->h.th->cwr) | ||
73 | tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR; | ||
74 | } | ||
75 | |||
76 | static inline void TCP_ECN_withdraw_cwr(struct tcp_sock *tp) | ||
77 | { | ||
78 | tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR; | ||
79 | } | ||
80 | |||
81 | static inline void TCP_ECN_check_ce(struct tcp_sock *tp, struct sk_buff *skb) | ||
82 | { | ||
83 | if (tp->ecn_flags&TCP_ECN_OK) { | ||
84 | if (INET_ECN_is_ce(TCP_SKB_CB(skb)->flags)) | ||
85 | tp->ecn_flags |= TCP_ECN_DEMAND_CWR; | ||
86 | /* Funny extension: if ECT is not set on a segment, | ||
87 | * it is surely retransmit. It is not in ECN RFC, | ||
88 | * but Linux follows this rule. */ | ||
89 | else if (INET_ECN_is_not_ect((TCP_SKB_CB(skb)->flags))) | ||
90 | tcp_enter_quickack_mode(tp); | ||
91 | } | ||
92 | } | ||
93 | |||
94 | static inline void TCP_ECN_rcv_synack(struct tcp_sock *tp, struct tcphdr *th) | ||
95 | { | ||
96 | if ((tp->ecn_flags&TCP_ECN_OK) && (!th->ece || th->cwr)) | ||
97 | tp->ecn_flags &= ~TCP_ECN_OK; | ||
98 | } | ||
99 | |||
100 | static inline void TCP_ECN_rcv_syn(struct tcp_sock *tp, struct tcphdr *th) | ||
101 | { | ||
102 | if ((tp->ecn_flags&TCP_ECN_OK) && (!th->ece || !th->cwr)) | ||
103 | tp->ecn_flags &= ~TCP_ECN_OK; | ||
104 | } | ||
105 | |||
106 | static inline int TCP_ECN_rcv_ecn_echo(struct tcp_sock *tp, struct tcphdr *th) | ||
107 | { | ||
108 | if (th->ece && !th->syn && (tp->ecn_flags&TCP_ECN_OK)) | ||
109 | return 1; | ||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | static inline void TCP_ECN_openreq_child(struct tcp_sock *tp, | ||
114 | struct open_request *req) | ||
115 | { | ||
116 | tp->ecn_flags = req->ecn_ok ? TCP_ECN_OK : 0; | ||
117 | } | ||
118 | |||
119 | static __inline__ void | ||
120 | TCP_ECN_create_request(struct open_request *req, struct tcphdr *th) | ||
121 | { | ||
122 | if (sysctl_tcp_ecn && th->ece && th->cwr) | ||
123 | req->ecn_ok = 1; | ||
124 | } | ||
125 | |||
126 | #endif | ||