Initial commit of vpp code.
[vpp.git] / vnet / vnet / ip / tcp.h
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /*
16  * ip/tcp.h: tcp protocol
17  *
18  * Copyright (c) 2011 Eliot Dresselhaus
19  *
20  * Permission is hereby granted, free of charge, to any person obtaining
21  * a copy of this software and associated documentation files (the
22  * "Software"), to deal in the Software without restriction, including
23  * without limitation the rights to use, copy, modify, merge, publish,
24  * distribute, sublicense, and/or sell copies of the Software, and to
25  * permit persons to whom the Software is furnished to do so, subject to
26  * the following conditions:
27  *
28  * The above copyright notice and this permission notice shall be
29  * included in all copies or substantial portions of the Software.
30  *
31  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38  */
39
40 #ifndef included_tcp_protocol_h
41 #define included_tcp_protocol_h
42
43 #include <vppinfra/vector.h>
44
45 /* No support for e.g. Altivec. */
46 #if defined (__SSE2__)
47 #define TCP_HAVE_VEC128
48 #endif
49
50 typedef union {
51   struct {
52     u16 src, dst;
53   };
54   u32 as_u32;
55 } tcp_udp_ports_t;
56
57 typedef union {
58 #ifdef TCP_HAVE_VEC128
59   u32x4 as_u32x4;
60 #endif
61   tcp_udp_ports_t as_ports[4];
62 } tcp_udp_ports_x4_t;
63
64 typedef struct {
65   union {
66 #ifdef TCP_HAVE_VEC128
67     u32x4 as_u32x4;
68 #endif
69     ip4_address_t as_ip4_address[4];
70   } src, dst;
71   tcp_udp_ports_x4_t ports;
72 } ip4_tcp_udp_address_x4_t;
73
74 typedef struct {
75   union {
76 #ifdef TCP_HAVE_VEC128
77     u32x4 as_u32x4[4];
78 #endif
79     u32   as_u32[4][4];
80   } src, dst;
81   tcp_udp_ports_x4_t ports;
82 } ip6_tcp_udp_address_x4_t;
83
84 typedef struct {
85   u32 his, ours;
86 } tcp_sequence_pair_t;
87
88 /* Time stamps saved from options. */
89 typedef struct {
90   u32 ours_host_byte_order, his_net_byte_order;
91 } tcp_time_stamp_pair_t;
92
93 typedef struct {
94   ip4_tcp_udp_address_x4_t address_x4;
95   u32 time_stamps[4];
96 } ip4_tcp_udp_address_x4_and_timestamps_t;
97
98 typedef struct {
99   ip6_tcp_udp_address_x4_t address_x4;
100   u32 time_stamps[4];
101 } ip6_tcp_udp_address_x4_and_timestamps_t;
102
103 #define foreach_tcp_connection_state                                    \
104   /* unused */                                                          \
105   _ (unused)                                                            \
106   /* Sent SYN-ACK waiting for ACK if he ever feels like sending one. */ \
107   _ (listen_ack_wait)                                                   \
108   /* Sent SYN waiting for ACK or RST. */                                \
109   _ (connecting)                                                        \
110   /* Pseudo-type for established connections. */                        \
111   _ (established)
112
113 typedef enum {
114 #define _(f) TCP_CONNECTION_STATE_##f,
115   foreach_tcp_connection_state
116 #undef _
117   TCP_N_CONNECTION_STATE,
118 } tcp_connection_state_t;
119
120 /* Kept small to fight off syn flood attacks. */
121 typedef struct {
122   tcp_sequence_pair_t sequence_numbers;
123
124   tcp_time_stamp_pair_t time_stamps;
125
126   /* segment size and window scale (saved from options
127      or set to defaults). */
128   u16 max_segment_size;
129
130   u8 window_scale;
131
132   tcp_connection_state_t state : 8;
133 } tcp_mini_connection_t;
134
135 typedef struct {
136   /* Sum and sum^2 of measurements.
137      Used to compute average and RMS. */
138   f64 sum, sum2;
139
140   /* Number of measurements. */
141   f64 count;
142 } tcp_round_trip_time_stats_t;
143
144 typedef struct {
145   u32 first_buffer_index_this_packet;
146
147   u16 data_ip_checksum;
148
149   u16 n_data_bytes;
150 } tcp_tx_packet_t;
151
152 typedef struct {
153   tcp_sequence_pair_t sequence_numbers;
154
155   tcp_time_stamp_pair_t time_stamps;
156
157   tcp_tx_packet_t head_packet, tx_tail_packet, write_tail_packet;
158
159   u32 write_tail_buffer_index;
160
161   tcp_round_trip_time_stats_t round_trip_time_stats;
162
163   /* Number of un-acknowledged bytes we've sent. */
164   u32 n_tx_unacked_bytes;
165
166   /* segment size and window scale (saved from options
167      or set to defaults). */
168   u16 max_segment_size;
169
170   /* Window from latest received packet. */
171   u16 his_window;
172
173   u16 my_window;
174
175   u8 his_window_scale;
176
177   u8 my_window_scale;
178
179   /* ip4/ip6 tos/ttl to use for packets we send. */
180   u8 tos, ttl;
181
182   u16 flags;
183 #define foreach_tcp_connection_flag             \
184   _ (ack_pending)                               \
185   _ (fin_received)                              \
186   _ (fin_sent)                                  \
187   _ (application_requested_close)
188
189   u8 listener_opaque[128
190                      - 1 * sizeof (tcp_sequence_pair_t)
191                      - 1 * sizeof (tcp_time_stamp_pair_t)
192                      - 3 * sizeof (tcp_tx_packet_t)
193                      - 1 * sizeof (tcp_round_trip_time_stats_t)
194                      - 2 * sizeof (u32)
195                      - 4 * sizeof (u16)
196                      - 4 * sizeof (u8)];
197 } tcp_connection_t;
198
199 typedef enum {
200   TCP_IP4,
201   TCP_IP6,
202   TCP_N_IP46,
203 } tcp_ip_4_or_6_t;
204
205 typedef enum {
206 #define _(f) LOG2_TCP_CONNECTION_FLAG_##f,
207   foreach_tcp_connection_flag
208 #undef _
209   N_TCP_CONNECTION_FLAG,
210 #define _(f) TCP_CONNECTION_FLAG_##f = 1 << LOG2_TCP_CONNECTION_FLAG_##f,
211   foreach_tcp_connection_flag
212 #undef _
213 } tcp_connection_flag_t;
214
215 typedef enum {
216   TCP_PACKET_TEMPLATE_SYN,
217   TCP_PACKET_TEMPLATE_SYN_ACK,
218   TCP_PACKET_TEMPLATE_ACK,
219   TCP_PACKET_TEMPLATE_FIN_ACK,
220   TCP_PACKET_TEMPLATE_RST_ACK,
221   TCP_N_PACKET_TEMPLATE,
222 } tcp_packet_template_type_t;
223
224 typedef struct {
225   vlib_packet_template_t vlib;
226
227   /* TCP checksum of template with zeros for all
228      variable fields.  Network byte order. */
229   u16 tcp_checksum_net_byte_order;
230
231   /* IP4 checksum. */
232   u16 ip4_checksum_net_byte_order;
233 } tcp_packet_template_t;
234
235 typedef struct {
236   u8 log2_n_mini_connection_hash_elts;
237   u8 log2_n_established_connection_hash_elts;
238   u8 is_ip6;
239
240   u32 mini_connection_hash_mask;
241   u32 established_connection_hash_mask;
242
243   uword * established_connection_overflow_hash;
244
245   tcp_mini_connection_t * mini_connections;
246
247   tcp_connection_t * established_connections;
248
249   /* Vector of established connection indices which need ACKs sent. */
250   u32 * connections_pending_acks;
251
252   /* Default valid_local_adjacency_bitmap for listeners who want to listen
253      for a given port in on all interfaces. */
254   uword * default_valid_local_adjacency_bitmap;
255
256   u32 output_node_index;
257
258   tcp_packet_template_t packet_templates[TCP_N_PACKET_TEMPLATE];
259 } ip46_tcp_main_t;
260
261 #define foreach_tcp_event                                       \
262   /* Received a SYN-ACK after sending a SYN to connect. */      \
263   _ (connection_established)                                    \
264   /* Received a reset (RST) after sending a SYN to connect. */  \
265   _ (connect_failed)                                            \
266   /* Received a FIN from an established connection. */          \
267   _ (fin_received)                                              \
268   _ (connection_closed)                                         \
269   /* Received a reset RST from an established connection. */    \
270   _ (reset_received)
271
272 typedef enum {
273 #define _(f) TCP_EVENT_##f,
274   foreach_tcp_event
275 #undef _
276 } tcp_event_type_t;
277
278 typedef void (tcp_event_function_t)
279   (u32 * connections,
280    tcp_event_type_t event_type);
281
282 typedef struct {
283   /* Bitmap indicating which of local (interface) addresses
284      we should listen on for this destination port. */
285   uword * valid_local_adjacency_bitmap;
286
287   /* Destination tcp/udp port to listen for connections. */
288   u16 dst_port;
289
290   u16 next_index;
291
292   u32 flags;
293
294   /* Connection indices for which event in event_function applies to. */
295   u32 * event_connections[TCP_N_IP46];
296   u32 * eof_connections[TCP_N_IP46];
297   u32 * close_connections[TCP_N_IP46];
298
299   tcp_event_function_t * event_function;
300 } tcp_listener_t;
301
302 typedef struct {
303   u8 next, error;
304 } tcp_lookup_disposition_t;
305
306 #define foreach_tcp_timer                       \
307   /* Used to rank mini connections. */          \
308   _ (mini_connection, 10e-3)                    \
309   /* Used for timestamps. */                    \
310   _ (timestamp, 1e-6)
311
312 typedef enum {
313 #define _(f,s) TCP_TIMER_##f,
314   foreach_tcp_timer
315 #undef _
316   TCP_N_TIMER,
317 } tcp_timer_type_t;
318
319 typedef struct {
320   ip46_tcp_main_t ip4, ip6;
321
322   /* Array of non-established connections, but soon-to be established connections. */
323   ip4_tcp_udp_address_x4_and_timestamps_t * ip4_mini_connection_address_hash;
324   ip6_tcp_udp_address_x4_and_timestamps_t * ip6_mini_connection_address_hash;
325
326   /* Vector of size log2_n_established_connection_hash_elts plus overflow. */
327   ip4_tcp_udp_address_x4_t * ip4_established_connection_address_hash;
328   ip6_tcp_udp_address_x4_t * ip6_established_connection_address_hash;
329
330   /* Jenkins hash seeds for established and mini hash tables. */
331   u32x4_union_t connection_hash_seeds[2][3];
332   u32x4_union_t connection_hash_masks[2];
333
334   /* Pool of listeners. */
335   tcp_listener_t * listener_pool;
336
337   /* Table mapping destination port to listener index. */
338   u16 * listener_index_by_dst_port;
339
340   tcp_lookup_disposition_t disposition_by_state_and_flags[TCP_N_CONNECTION_STATE][64];
341
342   u8 log2_clocks_per_tick[TCP_N_TIMER];
343
344   f64 secs_per_tick[TCP_N_TIMER];
345
346   /* Holds pointers to default and per-packet TCP options while
347      parsing a TCP packet's options. */
348   tcp_mini_connection_t option_decode_mini_connection_template;
349
350   /* Count of currently established connections. */
351   u32 n_established_connections[TCP_N_IP46];
352
353   u32 tx_buffer_free_list;
354   u32 tx_buffer_free_list_n_buffer_bytes;
355 } tcp_main_t;
356
357 /* Global TCP main structure. */
358 tcp_main_t tcp_main;
359
360 typedef struct {
361   /* Listen on this port. */
362   u16 port;
363
364 #define TCP_LISTENER_IP4 (1 << 0)
365 #define TCP_LISTENER_IP6 (1 << 1)
366   u16 flags;
367
368   /* Next node index for data packets. */
369   u32 data_node_index;
370
371   /* Event function: called on new connections, etc. */
372   tcp_event_function_t * event_function;
373 } tcp_listener_registration_t;
374
375 uword
376 tcp_register_listener (vlib_main_t * vm, tcp_listener_registration_t * r);
377
378 always_inline tcp_ip_4_or_6_t
379 tcp_connection_is_ip6 (u32 h)
380 { return h & 1; }
381
382 always_inline tcp_ip_4_or_6_t
383 tcp_connection_handle_set (u32 iest, tcp_ip_4_or_6_t is_ip6)
384 { return is_ip6 + 2*iest; }
385
386 always_inline tcp_connection_t *
387 tcp_get_connection (u32 connection_handle)
388 {
389   u32 iest = connection_handle / 2;
390   tcp_ip_4_or_6_t is_ip6 = tcp_connection_is_ip6 (connection_handle);
391   tcp_main_t * tm = &tcp_main;
392   ip46_tcp_main_t * tm46 = is_ip6 ? &tm->ip6 : &tm->ip4;
393   return vec_elt_at_index (tm46->established_connections, iest);
394 }
395
396 #endif /* included_tcp_protocol_h */