SCTP: shutdown phase
[vpp.git] / src / vnet / sctp / sctp.h
1 /*
2  * Copyright (c) 2017 SUSE LLC.
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 #ifndef included_vnet_sctp_h
16 #define included_vnet_sctp_h
17
18 #include <vnet/vnet.h>
19 #include <vnet/ip/ip.h>
20 #include <vnet/sctp/sctp_timer.h>
21 #include <vnet/sctp/sctp_packet.h>
22 #include <vnet/session/transport.h>
23 #include <vnet/session/session.h>
24
25 /* SCTP timers */
26 #define foreach_sctp_timer                      \
27   _(T1_INIT, "T1_INIT")                                 \
28   _(T1_COOKIE, "T1_COOKIE")                             \
29   _(T2_SHUTDOWN, "T2_SHUTDOWN")                 \
30   _(T3_RXTX, "T3_RXTX")                                         \
31   _(T4_HEARTBEAT, "T4_HB")                                      \
32   _(T5_SHUTDOWN_GUARD, "T5_SHUTDOWN_GUARD")
33
34 typedef enum _sctp_timers
35 {
36 #define _(sym, str) SCTP_TIMER_##sym,
37   foreach_sctp_timer
38 #undef _
39   SCTP_N_TIMERS
40 } sctp_timers_e;
41
42 #define SCTP_TIMER_HANDLE_INVALID ((u32) ~0)
43
44 always_inline char *
45 sctp_timer_to_string (u8 timer_id)
46 {
47   switch (timer_id)
48     {
49     case SCTP_TIMER_T1_INIT:
50       return "SCTP_TIMER_T1_INIT";
51     case SCTP_TIMER_T1_COOKIE:
52       return "SCTP_TIMER_T1_COOKIE";
53     case SCTP_TIMER_T2_SHUTDOWN:
54       return "SCTP_TIMER_T2_SHUTDOWN";
55     case SCTP_TIMER_T3_RXTX:
56       return "SCTP_TIMER_T3_RXTX";
57     case SCTP_TIMER_T4_HEARTBEAT:
58       return "SCTP_TIMER_T4_HEARTBEAT";
59     case SCTP_TIMER_T5_SHUTDOWN_GUARD:
60       return "SCTP_TIMER_T5_SHUTDOWN_GUARD";
61     }
62   return NULL;
63 }
64
65 typedef enum _sctp_error
66 {
67 #define sctp_error(n,s) SCTP_ERROR_##n,
68 #include <vnet/sctp/sctp_error.def>
69 #undef sctp_error
70   SCTP_N_ERROR,
71 } sctp_error_t;
72
73 #define NO_FLAG 0
74
75 #define IS_T_BIT_SET(var) ((var) & (1))
76 #define IS_E_BIT_SET(var) ((var) & (1))
77 #define IS_B_BIT_SET(var) ((var) & (1<<1))
78 #define IS_U_BIT_SET(var) ((var) & (1<<2))
79
80 #define MAX_SCTP_CONNECTIONS 32
81 #define MAIN_SCTP_SUB_CONN_IDX 0
82
83 #if (VLIB_BUFFER_TRACE_TRAJECTORY)
84 #define sctp_trajectory_add_start(b, start)                     \
85 {                                                               \
86     (*vlib_buffer_trace_trajectory_cb) (b, start);              \
87 }
88 #else
89 #define sctp_trajectory_add_start(b, start)
90 #endif
91
92 typedef struct _sctp_sub_connection
93 {
94   transport_connection_t connection;          /**< Common transport data. First! */
95   void *parent;                                                         /**< Link to the parent-super connection */
96
97   u32 error_count; /**< The current error count for this destination. */
98   u32 error_threshold; /**< Current error threshold for this destination,
99                                 i.e. what value marks the destination down if error count reaches this value. */
100   u32 cwnd; /**< The current congestion window. */
101   u32 ssthresh; /**< The current ssthresh value. */
102
103   u32 rtt_ts;   /**< USED to hold the timestamp of when the packet has been sent */
104
105   u32 RTO; /**< The current retransmission timeout value. */
106   u32 SRTT; /**< The current smoothed round-trip time. */
107   f32 RTTVAR; /**< The current RTT variation. */
108
109   u32 partially_acked_bytes; /**< The tracking method for increase of cwnd when in
110                                   congestion avoidance mode (see Section 7.2.2).*/
111
112   u8 state; /**< The current state of this destination, i.e., DOWN, UP, ALLOW-HB, NO-HEARTBEAT, etc. */
113
114   u16 PMTU; /**< The current known path MTU. */
115
116   u32 timers[SCTP_N_TIMERS]; /**< A timer used by each destination. */
117
118   u8 RTO_pending; /**< A flag used to track if one of the DATA chunks sent to
119                                   this address is currently being used to compute an RTT.
120                                   If this flag is 0, the next DATA chunk sent to this destination
121                                   should be used to compute an RTT and this flag should be set.
122                                   Every time the RTT calculation completes (i.e., the DATA chunk is SACK'd),
123                                   clear this flag. */
124
125   u32 last_time; /**< The time to which this destination was last sent a packet to.
126                                   This can be used to determine if a HEARTBEAT is needed. */
127
128   u8 unacknowledged_hb; /**< Used to track how many unacknowledged heartbeats we had;
129                                   If more than Max.Retransmit then connetion is considered unreachable. */
130
131 } sctp_sub_connection_t;
132
133 typedef struct
134 {
135   u32 a_rwnd; /**< Maximum segment size advertised */
136
137 } sctp_options_t;
138
139 /* Useful macros to deal with the out_of_order_map (array of bit) */
140 #define SET_BIT(A,k)     ( A[(k/32)] |= (1 << (k%32)) )
141 #define CLEAR_BIT(A,k)   ( A[(k/32)] &= ~(1 << (k%32)) )
142 #define TEST_BIT(A,k)    ( A[(k/32)] & (1 << (k%32)) )
143
144 always_inline void
145 _bytes_swap (void *pv, size_t n)
146 {
147   char *p = pv;
148   size_t lo, hi;
149   for (lo = 0, hi = n - 1; hi > lo; lo++, hi--)
150     {
151       char tmp = p[lo];
152       p[lo] = p[hi];
153       p[hi] = tmp;
154     }
155 }
156
157 #define ENDIANESS_SWAP(x) _bytes_swap(&x, sizeof(x));
158
159 #define MAX_INFLIGHT_PACKETS    128
160 #define MAX_ENQUEABLE_SACKS 2
161
162 /* This parameter indicates to the receiver how much increment in
163  * milliseconds the sender wishes the receiver to add to its default
164  * cookie life-span.
165  */
166 #define SUGGESTED_COOKIE_LIFE_SPAN_INCREMENT 1000
167
168 typedef struct _sctp_connection
169 {
170   sctp_sub_connection_t sub_conn[MAX_SCTP_CONNECTIONS]; /**< Common transport data. First! */
171
172   u8 state;                     /**< SCTP state as per sctp_state_t */
173   u16 flags;            /**< Chunk flag (see sctp_chunks_common_hdr_t) */
174
175   u32 local_tag;        /**< INIT_TAG generated locally */
176   u32 remote_tag;       /**< INIT_TAG generated by the remote peer */
177
178   u32 local_initial_tsn; /**< Initial TSN generated locally */
179   u32 remote_initial_tsn; /**< Initial TSN generated by the remote-peer */
180
181   u32 peer_cookie_life_span_increment;
182
183   u32 overall_err_count; /**< The overall association error count. */
184   u32 overall_err_treshold; /**< The threshold for this association that if the Overall Error Count
185                                   reaches will cause this association to be torn down. */
186
187   u32 peer_rwnd; /**< Current calculated value of the peer's rwnd. */
188
189   u32 next_tsn; /**< The next TSN number to be assigned to a new DATA chunk.
190                  This is sent in the INIT or INIT ACK chunk to the peer
191                  and incremented each time a DATA chunk is assigned a
192                  TSN (normally just prior to transmit or during
193                  fragmentation). */
194
195   u32 next_tsn_expected; /**< The next TSN number expected to be received. */
196
197   u32 last_rcvd_tsn; /**< This is the last TSN received in sequence. This value
198                          is set initially by taking the peer's initial TSN,
199                  received in the INIT or INIT ACK chunk, and
200                  subtracting one from it. */
201
202   u32 out_of_order_map[MAX_INFLIGHT_PACKETS]; /**< An array of bits or bytes indicating which out-of-order
203                                 TSNs have been received (relative to the Last Rcvd TSN).
204                                 If no gaps exist, i.e., no out-of-order packets have been received,
205                                 this array will be set to all zero. */
206
207   u8 ack_state; /**< This flag indicates if the next received packet is set to be responded to with a SACK.
208                                 This is initialized to 0. When a packet is received it is incremented.
209                                 If this value reaches 2 or more, a SACK is sent and the value is reset to 0.
210                                 Note: This is used only when no DATA chunks are received out-of-order.
211                                 When DATA chunks are out-of-order, SACKs are not delayed (see Section 6). */
212
213   u32 a_rwnd; /** This value represents the dedicated buffer space, in number of bytes,
214                                 the sender of the INIT has reserved in association with this window.
215                                 During the life of the association, this buffer space SHOULD NOT be lessened
216                                 (i.e., dedicated buffers taken away from this association);
217                                 however, an endpoint MAY change the value of a_rwnd it sends in SACK chunks. */
218
219   u32 smallest_PMTU; /** The smallest PMTU discovered for all of the peer's transport addresses. */
220
221   u32 rcv_a_rwnd;               /**< LOCAL max seg size that includes options. To be updated by congestion algos, etc. */
222   u32 snd_a_rwnd;               /**< REMOTE max seg size that includes options. To be updated if peer pushes back on window, etc.*/
223
224   u8 overall_sending_status; /**< 0 indicates first fragment of a user message
225                                                                   1 indicates normal stream
226                                                                   2 indicates last fragment of a user message */
227
228   sctp_options_t rcv_opts;
229   sctp_options_t snd_opts;
230
231   u32 snd_hdr_length;   /**< BASE HEADER LENGTH for the DATA chunk when sending */
232   u8 next_avail_sub_conn; /**< Represent the index of the next free slot in sub_conn */
233
234 } sctp_connection_t;
235
236 typedef void (sctp_timer_expiration_handler) (u32 conn_index, u32 timer_id);
237
238 sctp_connection_t *sctp_connection_new (u8 thread_index);
239 void sctp_sub_connection_add_ip4 (u8 thread_index,
240                                   sctp_ipv4_addr_param_t * ipv4_addr);
241 void sctp_sub_connection_add_ip6 (u8 thread_index,
242                                   sctp_ipv6_addr_param_t * ipv6_addr);
243 void sctp_connection_close (sctp_connection_t * sctp_conn);
244 void sctp_connection_cleanup (sctp_connection_t * sctp_conn);
245 void sctp_connection_del (sctp_connection_t * sctp_conn);
246
247 u32 sctp_push_header (transport_connection_t * tconn, vlib_buffer_t * b);
248 void sctp_send_init (sctp_connection_t * sctp_conn);
249 void sctp_send_shutdown (sctp_connection_t * sctp_conn);
250 void sctp_send_shutdown_ack (sctp_connection_t * sctp_conn,
251                              vlib_buffer_t * b);
252 void sctp_send_shutdown_complete (sctp_connection_t * sctp_conn);
253 void sctp_send_heartbeat (sctp_connection_t * sctp_conn);
254 void sctp_flush_frame_to_output (vlib_main_t * vm, u8 thread_index,
255                                  u8 is_ip4);
256 void sctp_flush_frames_to_output (u8 thread_index);
257 void sctp_punt_unknown (vlib_main_t * vm, u8 is_ip4, u8 is_add);
258
259 format_function_t format_sctp_state;
260
261 u8 *format_sctp_connection_id (u8 * s, va_list * args);
262 u8 *format_sctp_connection (u8 * s, va_list * args);
263 u8 *format_sctp_scoreboard (u8 * s, va_list * args);
264 u8 *format_sctp_header (u8 * s, va_list * args);
265 u8 *format_sctp_tx_trace (u8 * s, va_list * args);
266
267 clib_error_t *sctp_init (vlib_main_t * vm);
268 void sctp_connection_timers_init (sctp_connection_t * tc);
269 void sctp_connection_timers_reset (sctp_connection_t * tc);
270 void sctp_init_snd_vars (sctp_connection_t * tc);
271 void sctp_init_mss (sctp_connection_t * tc);
272
273 void sctp_prepare_initack_chunk (sctp_connection_t * ts, vlib_buffer_t * b,
274                                  ip4_address_t * ip4_addr,
275                                  ip6_address_t * ip6_addr);
276 void sctp_prepare_cookie_echo_chunk (sctp_connection_t * tc,
277                                      vlib_buffer_t * b,
278                                      sctp_state_cookie_param_t * sc);
279 void sctp_prepare_cookie_ack_chunk (sctp_connection_t * tc,
280                                     vlib_buffer_t * b);
281 void sctp_prepare_sack_chunk (sctp_connection_t * tc, vlib_buffer_t * b);
282 void sctp_prepare_heartbeat_ack_chunk (sctp_connection_t * sctp_conn,
283                                        vlib_buffer_t * b);
284
285 u16 sctp_check_outstanding_data_chunks (sctp_connection_t * tc);
286
287 #define SCTP_TICK 0.001                 /**< SCTP tick period (s) */
288 #define STHZ (u32) (1/SCTP_TICK)                /**< SCTP tick frequency */
289 #define SCTP_TSTAMP_RESOLUTION SCTP_TICK        /**< Time stamp resolution */
290 #define SCTP_PAWS_IDLE 24 * 24 * 60 * 60 * THZ /**< 24 days */
291 #define SCTP_FIB_RECHECK_PERIOD 1 * THZ /**< Recheck every 1s */
292 #define SCTP_MAX_OPTION_SPACE 40
293
294 #define SCTP_DUPACK_THRESHOLD   3
295 #define SCTP_MAX_RX_FIFO_SIZE   4 << 20
296 #define SCTP_MIN_RX_FIFO_SIZE   4 << 10
297 #define SCTP_IW_N_SEGMENTS      10
298 #define SCTP_ALWAYS_ACK         1       /**< On/off delayed acks */
299 #define SCTP_USE_SACKS          1       /**< Disable only for testing */
300
301 #define IP_PROTOCOL_SCTP        132
302
303 /** SSCTP FSM state definitions as per RFC4960. */
304 #define foreach_sctp_fsm_state                \
305   _(CLOSED, "CLOSED")                         \
306   _(COOKIE_WAIT, "COOKIE_WAIT")               \
307   _(COOKIE_ECHOED, "COOKIE_ECHOED")           \
308   _(ESTABLISHED, "ESTABLISHED")               \
309   _(SHUTDOWN_PENDING, "SHUTDOWN_PENDING")     \
310   _(SHUTDOWN_SENT, "SHUTDOWN_SENT")           \
311   _(SHUTDOWN_RECEIVED, "SHUTDOWN_RECEIVED")   \
312   _(SHUTDOWN_ACK_SENT, "SHUTDOWN_ACK_SENT")
313
314 typedef enum _sctp_state
315 {
316 #define _(sym, str) SCTP_STATE_##sym,
317   foreach_sctp_fsm_state
318 #undef _
319   SCTP_N_STATES
320 } sctp_state_t;
321
322 always_inline char *
323 sctp_state_to_string (u8 state)
324 {
325   switch (state)
326     {
327     case SCTP_STATE_CLOSED:
328       return "SCTP_STATE_CLOSED";
329     case SCTP_STATE_COOKIE_WAIT:
330       return "SCTP_STATE_COOKIE_WAIT";
331     case SCTP_STATE_COOKIE_ECHOED:
332       return "SCTP_STATE_COOKIE_ECHOED";
333     case SCTP_STATE_ESTABLISHED:
334       return "SCTP_STATE_ESTABLISHED";
335     case SCTP_STATE_SHUTDOWN_PENDING:
336       return "SCTP_STATE_SHUTDOWN_PENDING";
337     case SCTP_STATE_SHUTDOWN_SENT:
338       return "SCTP_STATE_SHUTDOWN_SENT";
339     case SCTP_STATE_SHUTDOWN_RECEIVED:
340       return "SCTP_STATE_SHUTDOWN_RECEIVED";
341     case SCTP_STATE_SHUTDOWN_ACK_SENT:
342       return "SCTP_STATE_SHUTDOWN_ACK_SENT";
343     }
344   return NULL;
345 }
346
347 always_inline char *
348 sctp_chunk_to_string (u8 type)
349 {
350   switch (type)
351     {
352     case DATA:
353       return "DATA";
354     case INIT:
355       return "INIT";
356     case INIT_ACK:
357       return "INIT_ACK";
358     case SACK:
359       return "SACK";
360     case HEARTBEAT:
361       return "HEARTBEAT";
362     case HEARTBEAT_ACK:
363       return "HEARTBEAT_ACK";
364     case ABORT:
365       return "ABORT";
366     case SHUTDOWN:
367       return "SHUTDOWN";
368     case SHUTDOWN_ACK:
369       return "SHUTDOWN_ACK";
370     case OPERATION_ERROR:
371       return "OPERATION_ERROR";
372     case COOKIE_ECHO:
373       return "COOKIE_ECHO";
374     case COOKIE_ACK:
375       return "COOKIE_ACK";
376     case ECNE:
377       return "ECNE";
378     case CWR:
379       return "CWR";
380     case SHUTDOWN_COMPLETE:
381       return "SHUTDOWN_COMPLETE";
382     }
383   return NULL;
384 }
385
386 always_inline char *
387 sctp_optparam_type_to_string (u8 type)
388 {
389   switch (type)
390     {
391     case SCTP_IPV4_ADDRESS_TYPE:
392       return "SCTP_IPV4_ADDRESS_TYPE";
393     case SCTP_IPV6_ADDRESS_TYPE:
394       return "SCTP_IPV6_ADDRESS_TYPE";
395     case SCTP_STATE_COOKIE_TYPE:
396       return "SCTP_STATE_COOKIE_TYPE";
397     case SCTP_UNRECOGNIZED_TYPE:
398       return "SCTP_UNRECOGNIZED_TYPE";
399     case SCTP_COOKIE_PRESERVATIVE_TYPE:
400       return "SCTP_COOKIE_PRESERVATIVE_TYPE";
401     case SCTP_HOSTNAME_ADDRESS_TYPE:
402       return "SCTP_HOSTNAME_ADDRESS_TYPE";
403     case SCTP_SUPPORTED_ADDRESS_TYPES:
404       return "SCTP_SUPPORTED_ADDRESS_TYPES";
405     }
406   return NULL;
407 }
408
409 #define SCTP_TICK 0.001                 /**< SCTP tick period (s) */
410 #define SHZ (u32) (1/SCTP_TICK)         /**< SCTP tick frequency */
411
412 /* As per RFC4960, page 83 */
413 #define SCTP_RTO_INIT 3 * SHZ   /* 3 seconds */
414 #define SCTP_RTO_MIN 1 * SHZ    /* 1 second */
415 #define SCTP_RTO_MAX 60 * SHZ   /* 60 seconds */
416 #define SCTP_RTO_BURST  4
417 #define SCTP_RTO_ALPHA 1/8
418 #define SCTP_RTO_BETA 1/4
419 #define SCTP_VALID_COOKIE_LIFE 60 * SHZ /* 60 seconds */
420 #define SCTP_ASSOCIATION_MAX_RETRANS 10
421
422 #define SCTP_TO_TIMER_TICK       SCTP_TICK*10   /* Period for converting from SCTP_TICK */
423
424 typedef struct _sctp_lookup_dispatch
425 {
426   u8 next, error;
427 } sctp_lookup_dispatch_t;
428
429 typedef struct _sctp_main
430 {
431   /* Per-worker thread SCTP connection pools */
432   sctp_connection_t **connections;
433
434   /* Pool of listeners. */
435   sctp_connection_t *listener_pool;
436
437           /** Dispatch table by state and flags */
438   sctp_lookup_dispatch_t dispatch_table[SCTP_N_STATES][64];
439
440   u8 log2_tstamp_clocks_per_tick;
441   f64 tstamp_ticks_per_clock;
442   u32 *time_now;
443
444           /** per-worker tx buffer free lists */
445   u32 **tx_buffers;
446           /** per-worker tx frames to SCTP 4/6 output nodes */
447   vlib_frame_t **tx_frames[2];
448           /** per-worker tx frames to ip 4/6 lookup nodes */
449   vlib_frame_t **ip_lookup_tx_frames[2];
450
451   /* Per worker-thread timer wheel for connections timers */
452   tw_timer_wheel_16t_2w_512sl_t *timer_wheels;
453
454   /* Pool of half-open connections on which we've sent a SYN */
455   sctp_connection_t *half_open_connections;
456   clib_spinlock_t half_open_lock;
457
458   /* TODO: Congestion control algorithms registered */
459   /* sctp_cc_algorithm_t *cc_algos; */
460
461   /* Flag that indicates if stack is on or off */
462   u8 is_enabled;
463
464           /** Number of preallocated connections */
465   u32 preallocated_connections;
466
467           /** Transport table (preallocation) size parameters */
468   u32 local_endpoints_table_memory;
469   u32 local_endpoints_table_buckets;
470
471           /** Vectors of src addresses. Optional unless one needs > 63K active-opens */
472   ip4_address_t *ip4_src_addresses;
473   u32 last_v4_address_rotor;
474   u32 last_v6_address_rotor;
475   ip6_address_t *ip6_src_addresses;
476
477           /** vlib buffer size */
478   u32 bytes_per_buffer;
479
480   u8 punt_unknown4;
481   u8 punt_unknown6;
482
483 } sctp_main_t;
484
485 extern sctp_main_t sctp_main;
486 extern vlib_node_registration_t sctp4_input_node;
487 extern vlib_node_registration_t sctp6_input_node;
488 extern vlib_node_registration_t sctp4_output_node;
489 extern vlib_node_registration_t sctp6_output_node;
490
491 always_inline sctp_main_t *
492 vnet_get_sctp_main ()
493 {
494   return &sctp_main;
495 }
496
497 always_inline sctp_header_t *
498 sctp_buffer_hdr (vlib_buffer_t * b)
499 {
500   ASSERT ((signed) b->current_data >= (signed) -VLIB_BUFFER_PRE_DATA_SIZE);
501   return (sctp_header_t *) (b->data + b->current_data
502                             + vnet_buffer (b)->sctp.hdr_offset);
503 }
504
505 clib_error_t *vnet_sctp_enable_disable (vlib_main_t * vm, u8 is_en);
506
507 always_inline sctp_connection_t *
508 sctp_half_open_connection_get (u32 conn_index)
509 {
510   sctp_connection_t *tc = 0;
511   clib_spinlock_lock_if_init (&sctp_main.half_open_lock);
512   if (!pool_is_free_index (sctp_main.half_open_connections, conn_index))
513     tc = pool_elt_at_index (sctp_main.half_open_connections, conn_index);
514   tc->sub_conn[MAIN_SCTP_SUB_CONN_IDX].parent = tc;
515   clib_spinlock_unlock_if_init (&sctp_main.half_open_lock);
516   return tc;
517 }
518
519 /**
520  * Cleanup half-open connection
521  *
522  */
523 always_inline void
524 sctp_half_open_connection_del (sctp_connection_t * tc)
525 {
526   sctp_main_t *tm = vnet_get_sctp_main ();
527   clib_spinlock_lock_if_init (&tm->half_open_lock);
528   pool_put_index (tm->half_open_connections,
529                   tc->sub_conn[MAIN_SCTP_SUB_CONN_IDX].c_c_index);
530   if (CLIB_DEBUG)
531     memset (tc, 0xFA, sizeof (*tc));
532   clib_spinlock_unlock_if_init (&tm->half_open_lock);
533 }
534
535 always_inline u32
536 sctp_set_time_now (u32 thread_index)
537 {
538   sctp_main.time_now[thread_index] = clib_cpu_time_now ()
539     * sctp_main.tstamp_ticks_per_clock;
540   return sctp_main.time_now[thread_index];
541 }
542
543 always_inline void
544 sctp_timer_set (sctp_connection_t * tc, u8 conn_idx, u8 timer_id,
545                 u32 interval)
546 {
547   ASSERT (tc->sub_conn[conn_idx].connection.thread_index ==
548           vlib_get_thread_index ());
549   ASSERT (tc->sub_conn[conn_idx].timers[timer_id] ==
550           SCTP_TIMER_HANDLE_INVALID);
551
552   sctp_sub_connection_t *sub = &tc->sub_conn[conn_idx];
553   sub->timers[timer_id] =
554     tw_timer_start_16t_2w_512sl (&sctp_main.timer_wheels[sub->c_thread_index],
555                                  sub->c_c_index, timer_id, interval);
556 }
557
558 always_inline void
559 sctp_timer_reset (sctp_connection_t * tc, u8 conn_idx, u8 timer_id)
560 {
561   ASSERT (tc->sub_conn[conn_idx].c_thread_index == vlib_get_thread_index ());
562   if (tc->sub_conn[conn_idx].timers[timer_id] == SCTP_TIMER_HANDLE_INVALID)
563     return;
564
565   sctp_sub_connection_t *sub = &tc->sub_conn[conn_idx];
566
567   tw_timer_stop_16t_2w_512sl (&sctp_main.timer_wheels[sub->c_thread_index],
568                               sub->timers[timer_id]);
569   sub->timers[timer_id] = SCTP_TIMER_HANDLE_INVALID;
570 }
571
572 /**
573  * Try to cleanup half-open connection
574  *
575  * If called from a thread that doesn't own tc, the call won't have any
576  * effect.
577  *
578  * @param tc - connection to be cleaned up
579  * @return non-zero if cleanup failed.
580  */
581 always_inline int
582 sctp_half_open_connection_cleanup (sctp_connection_t * tc)
583 {
584   /* Make sure this is the owning thread */
585   if (tc->sub_conn[MAIN_SCTP_SUB_CONN_IDX].c_thread_index !=
586       vlib_get_thread_index ())
587     return 1;
588   sctp_timer_reset (tc, MAIN_SCTP_SUB_CONN_IDX, SCTP_TIMER_T1_INIT);
589   sctp_half_open_connection_del (tc);
590   return 0;
591 }
592
593 always_inline u32
594 sctp_header_bytes ()
595 {
596   return sizeof (sctp_header_t);
597 }
598
599 always_inline sctp_connection_t *
600 sctp_get_connection_from_transport (transport_connection_t * tconn)
601 {
602   ASSERT (tconn != NULL);
603
604   sctp_sub_connection_t *sub = (sctp_sub_connection_t *) tconn;
605 #if SCTP_ADV_DEBUG
606   if (sub == NULL)
607     SCTP_ADV_DBG ("sub == NULL");
608   if (sub->parent == NULL)
609     SCTP_ADV_DBG ("sub->parent == NULL");
610 #endif
611   return (sctp_connection_t *) sub->parent;
612 }
613
614 always_inline u32
615 sctp_time_now (void)
616 {
617   return sctp_main.time_now[vlib_get_thread_index ()];
618 }
619
620 #define ABS(x) ((x) > 0) ? (x) : -(x);
621
622 always_inline void
623 sctp_calculate_rto (sctp_connection_t * sctp_conn, u8 conn_idx)
624 {
625   /* See RFC4960, 6.3.1.  RTO Calculation */
626   u32 RTO = 0;
627   f32 RTTVAR = 0;
628   u32 now = sctp_time_now ();
629   u32 prev_ts = sctp_conn->sub_conn[conn_idx].rtt_ts;
630   u32 R = prev_ts - now;
631
632   if (sctp_conn->sub_conn[conn_idx].RTO == 0)   // C1: Let's initialize our RTO
633     {
634       sctp_conn->sub_conn[conn_idx].RTO = SCTP_RTO_MIN;
635       return;
636     }
637
638   if (sctp_conn->sub_conn[conn_idx].RTO == SCTP_RTO_MIN && sctp_conn->sub_conn[conn_idx].SRTT == 0)     // C2: First RTT calculation
639     {
640       sctp_conn->sub_conn[conn_idx].SRTT = R;
641       RTTVAR = R / 2;
642
643       if (RTTVAR == 0)
644         RTTVAR = 100e-3;        /* 100 ms */
645
646       sctp_conn->sub_conn[conn_idx].RTTVAR = RTTVAR;
647     }
648   else                          // C3: RTT already exists; let's recalculate
649     {
650       RTTVAR = (1 - SCTP_RTO_BETA) * sctp_conn->sub_conn[conn_idx].RTTVAR +
651         SCTP_RTO_BETA * ABS (sctp_conn->sub_conn[conn_idx].SRTT - R);
652
653       if (RTTVAR == 0)
654         RTTVAR = 100e-3;        /* 100 ms */
655
656       sctp_conn->sub_conn[conn_idx].RTTVAR = RTTVAR;
657
658       sctp_conn->sub_conn[conn_idx].SRTT =
659         (1 - SCTP_RTO_ALPHA) * sctp_conn->sub_conn[conn_idx].SRTT +
660         SCTP_RTO_ALPHA * R;
661     }
662
663   RTO =
664     sctp_conn->sub_conn[conn_idx].SRTT +
665     4 * sctp_conn->sub_conn[conn_idx].RTTVAR;
666   if (RTO < SCTP_RTO_MIN)       // C6
667     RTO = SCTP_RTO_MIN;
668
669   if (RTO > SCTP_RTO_MAX)       // C7
670     RTO = SCTP_RTO_MAX;
671
672   sctp_conn->sub_conn[conn_idx].RTO = RTO;
673 }
674
675 always_inline void
676 sctp_timer_update (sctp_connection_t * tc, u8 conn_idx, u8 timer_id,
677                    u32 interval)
678 {
679   ASSERT (tc->sub_conn[conn_idx].connection.thread_index ==
680           vlib_get_thread_index ());
681   sctp_sub_connection_t *sub = &tc->sub_conn[conn_idx];
682
683   if (tc->sub_conn[conn_idx].timers[timer_id] != SCTP_TIMER_HANDLE_INVALID)
684     tw_timer_stop_16t_2w_512sl (&sctp_main.timer_wheels[sub->c_thread_index],
685                                 sub->timers[timer_id]);
686
687   tc->sub_conn[conn_idx].timers[timer_id] =
688     tw_timer_start_16t_2w_512sl (&sctp_main.timer_wheels[sub->c_thread_index],
689                                  sub->c_c_index, timer_id, interval);
690 }
691
692 always_inline sctp_connection_t *
693 sctp_listener_get (u32 tli)
694 {
695   return pool_elt_at_index (sctp_main.listener_pool, tli);
696 }
697
698 #endif
699
700 always_inline sctp_connection_t *
701 sctp_connection_get (u32 conn_index, u32 thread_index)
702 {
703   if (PREDICT_FALSE
704       (pool_is_free_index (sctp_main.connections[thread_index], conn_index)))
705     return 0;
706   return pool_elt_at_index (sctp_main.connections[thread_index], conn_index);
707 }
708
709 always_inline u8
710 sctp_pick_conn_idx_on_chunk (sctp_chunk_type chunk_type)
711 {
712   u8 idx = MAIN_SCTP_SUB_CONN_IDX;
713
714   switch (chunk_type)
715     {
716     case DATA:
717     case INIT:
718     case INIT_ACK:
719     case SACK:
720     case HEARTBEAT:
721     case HEARTBEAT_ACK:
722     case ABORT:
723     case SHUTDOWN:
724     case SHUTDOWN_ACK:
725     case OPERATION_ERROR:
726     case COOKIE_ECHO:
727     case COOKIE_ACK:
728     case ECNE:
729     case CWR:
730     case SHUTDOWN_COMPLETE:
731       idx = MAIN_SCTP_SUB_CONN_IDX;
732     }
733   return idx;
734 }
735
736 always_inline u8
737 sctp_pick_conn_idx_on_state (sctp_state_t state)
738 {
739   u8 idx = MAIN_SCTP_SUB_CONN_IDX;
740
741   switch (state)
742     {
743     case SCTP_STATE_CLOSED:
744     case SCTP_STATE_COOKIE_WAIT:
745     case SCTP_STATE_COOKIE_ECHOED:
746     case SCTP_STATE_ESTABLISHED:
747     case SCTP_STATE_SHUTDOWN_PENDING:
748     case SCTP_STATE_SHUTDOWN_SENT:
749     case SCTP_STATE_SHUTDOWN_RECEIVED:
750     case SCTP_STATE_SHUTDOWN_ACK_SENT:
751       idx = MAIN_SCTP_SUB_CONN_IDX;
752     default:
753       idx = MAIN_SCTP_SUB_CONN_IDX;
754     }
755   return idx;
756 }
757
758 /**
759  * Push SCTP header to buffer
760  *
761  * @param vm - vlib_main
762  * @param b - buffer to write the header to
763  * @param sp_net - source port net order
764  * @param dp_net - destination port net order
765  * @param sctp_hdr_opts_len - header and options length in bytes
766  *
767  * @return - pointer to start of SCTP header
768  */
769 always_inline void *
770 vlib_buffer_push_sctp_net_order (vlib_buffer_t * b, u16 sp, u16 dp,
771                                  u8 sctp_hdr_opts_len)
772 {
773   sctp_full_hdr_t *full_hdr;
774
775   full_hdr = vlib_buffer_push_uninit (b, sctp_hdr_opts_len);
776
777   full_hdr->hdr.src_port = sp;
778   full_hdr->hdr.dst_port = dp;
779   full_hdr->hdr.checksum = 0;
780   return full_hdr;
781 }
782
783 /**
784  * Push SCTP header to buffer
785  *
786  * @param b - buffer to write the header to
787  * @param sp_net - source port net order
788  * @param dp_net - destination port net order
789  * @param sctp_hdr_opts_len - header and options length in bytes
790  *
791  * @return - pointer to start of SCTP header
792  */
793 always_inline void *
794 vlib_buffer_push_sctp (vlib_buffer_t * b, u16 sp_net, u16 dp_net,
795                        u8 sctp_hdr_opts_len)
796 {
797   return vlib_buffer_push_sctp_net_order (b, sp_net, dp_net,
798                                           sctp_hdr_opts_len);
799 }
800
801 /*
802  * fd.io coding-style-patch-verification: ON
803  *
804  * Local Variables:
805  * eval: (c-set-style "gnu")
806  * End:
807  */