blob: d032a3dc749ba313c7ee5134844f30e9b5c78faa [file] [log] [blame]
Dave Barach68b0fb02017-02-28 15:15:56 -05001/*
Florin Coras222e1f412019-02-16 20:47:32 -08002 * Copyright (c) 2016-2019 Cisco and/or its affiliates.
Dave Barach68b0fb02017-02-28 15:15:56 -05003 * 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#ifndef _vnet_tcp_h_
17#define _vnet_tcp_h_
18
19#include <vnet/vnet.h>
20#include <vnet/ip/ip.h>
Dave Barach68b0fb02017-02-28 15:15:56 -050021#include <vnet/session/session.h>
Florin Coras999840c2020-03-18 20:31:34 +000022#include <vnet/tcp/tcp_types.h>
23#include <vnet/tcp/tcp_timer.h>
Florin Corase69f4952017-03-07 10:06:24 -080024#include <vnet/tcp/tcp_debug.h>
Florin Coras999840c2020-03-18 20:31:34 +000025#include <vnet/tcp/tcp_sack.h>
26#include <vnet/tcp/tcp_bt.h>
27#include <vnet/tcp/tcp_cc.h>
Florin Corasbbcfaac2019-10-10 13:52:04 -070028
Florin Corasaa388692020-02-14 23:41:25 +000029typedef void (timer_expiration_handler) (tcp_connection_t * tc);
30
Florin Corasaa388692020-02-14 23:41:25 +000031extern timer_expiration_handler tcp_timer_retransmit_handler;
32extern timer_expiration_handler tcp_timer_persist_handler;
33extern timer_expiration_handler tcp_timer_retransmit_syn_handler;
34
Dave Barach68b0fb02017-02-28 15:15:56 -050035typedef enum _tcp_error
36{
Filip Tehlar0c4931c2021-10-06 09:47:41 +000037#define tcp_error(f, n, s, d) TCP_ERROR_##f,
Dave Barach68b0fb02017-02-28 15:15:56 -050038#include <vnet/tcp/tcp_error.def>
39#undef tcp_error
40 TCP_N_ERROR,
41} tcp_error_t;
42
43typedef struct _tcp_lookup_dispatch
44{
45 u8 next, error;
46} tcp_lookup_dispatch_t;
47
Florin Coras5e6305f2020-02-12 07:42:01 +000048#define foreach_tcp_wrk_stat \
49 _(timer_expirations, u64, "timer expirations") \
50 _(rxt_segs, u64, "segments retransmitted") \
51 _(tr_events, u32, "timer retransmit events") \
52 _(to_closewait, u32, "timeout close-wait") \
Florin Corasaa388692020-02-14 23:41:25 +000053 _(to_closewait2, u32, "timeout close-wait w/data") \
Florin Coras5e6305f2020-02-12 07:42:01 +000054 _(to_finwait1, u32, "timeout fin-wait-1") \
Florin Coras3f78bbb2020-02-13 19:24:58 +000055 _(to_finwait2, u32, "timeout fin-wait-2") \
Florin Coras5e6305f2020-02-12 07:42:01 +000056 _(to_lastack, u32, "timeout last-ack") \
57 _(to_closing, u32, "timeout closing") \
58 _(tr_abort, u32, "timer retransmit abort") \
59 _(rst_unread, u32, "reset on close due to unread data") \
Florin Corasd4712a82020-05-22 21:51:30 +000060 _(no_buffer, u32, "out of buffers") \
Florin Coras5e6305f2020-02-12 07:42:01 +000061
62typedef struct tcp_wrk_stats_
63{
64#define _(name, type, str) type name;
65 foreach_tcp_wrk_stat
66#undef _
67} tcp_wrk_stats_t;
68
Florin Coras6052f4b2023-06-21 20:02:25 -070069typedef enum
70{
71#define _(name, type, str) TCP_STAT_##name,
72 foreach_tcp_wrk_stat
73#undef _
74} tcp_wrk_stats_e;
75
Florin Coras7a3a8662020-02-22 02:27:21 +000076typedef struct tcp_free_req_
77{
78 clib_time_type_t free_time;
79 u32 connection_index;
80} tcp_cleanup_req_t;
81
Florin Coras2c414432018-06-19 09:58:04 -070082typedef struct tcp_worker_ctx_
83{
84 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
Florin Corasb11175d2018-11-09 14:34:08 -080085
Florin Coras04261852020-02-12 01:24:29 +000086 /** worker's pool of connections */
87 tcp_connection_t *connections;
Florin Corasb11175d2018-11-09 14:34:08 -080088
Florin Corasb11175d2018-11-09 14:34:08 -080089 /** vector of pending ack dequeues */
Florin Coras9ece3c02018-11-05 11:06:53 -080090 u32 *pending_deq_acked;
Florin Corasb11175d2018-11-09 14:34:08 -080091
Florin Corasb11175d2018-11-09 14:34:08 -080092 /** vector of pending disconnect notifications */
93 u32 *pending_disconnects;
94
Florin Coras04261852020-02-12 01:24:29 +000095 /** vector of pending reset notifications */
Florin Coras6939d5e2020-02-10 23:22:34 +000096 u32 *pending_resets;
97
Florin Corasb11175d2018-11-09 14:34:08 -080098 /** convenience pointer to this thread's vlib main */
99 vlib_main_t *vm;
Florin Corasbf4d5ce2018-10-19 16:26:24 -0700100
Florin Coras8f10b902021-04-02 18:32:00 -0700101 /** Time used for high precision (us) measurements in seconds */
102 f64 time_us;
103
Florin Coraseedc74b2020-07-31 12:32:40 -0700104 /** Time measured in @ref TCP_TSTAMP_TICK used for time stamps */
Florin Coras8f10b902021-04-02 18:32:00 -0700105 u32 time_tstamp;
Florin Coras6939d5e2020-02-10 23:22:34 +0000106
Florin Corasa9d8cb42020-02-20 05:45:31 +0000107 /* Max timers to be handled per dispatch loop */
108 u32 max_timers_per_loop;
109
Florin Coras5484daa2020-03-27 23:55:06 +0000110 /* Fifo of pending timer expirations */
111 u32 *pending_timers;
Florin Coras04261852020-02-12 01:24:29 +0000112
Florin Corasb26743d2018-06-26 09:31:04 -0700113 CLIB_CACHE_LINE_ALIGN_MARK (cacheline1);
Florin Corasb11175d2018-11-09 14:34:08 -0800114
115 /** cached 'on the wire' options for bursts */
116 u8 cached_opts[40];
Florin Corasbf4d5ce2018-10-19 16:26:24 -0700117
Florin Coras04261852020-02-12 01:24:29 +0000118 /** tx buffer free list */
119 u32 *tx_buffers;
120
Florin Coras7a3a8662020-02-22 02:27:21 +0000121 /* fifo of pending free requests */
122 tcp_cleanup_req_t *pending_cleanups;
123
Florin Coras8f10b902021-04-02 18:32:00 -0700124 /** Session layer edge indices to tcp output */
125 u32 tco_next_node[2];
126
Florin Coras6939d5e2020-02-10 23:22:34 +0000127 /** worker timer wheel */
Florin Coras0765d972020-03-18 21:26:41 +0000128 tcp_timer_wheel_t timer_wheel;
Florin Coras6939d5e2020-02-10 23:22:34 +0000129
Florin Coras5e6305f2020-02-12 07:42:01 +0000130 CLIB_CACHE_LINE_ALIGN_MARK (cacheline2);
131
132 tcp_wrk_stats_t stats;
Florin Coras2c414432018-06-19 09:58:04 -0700133} tcp_worker_ctx_t;
134
Florin Coras0765d972020-03-18 21:26:41 +0000135#define tcp_worker_stats_inc(_wrk,_stat,_val) \
Florin Coras5e6305f2020-02-12 07:42:01 +0000136 _wrk->stats._stat += _val
137
Florin Coras18e0d4f2019-01-02 12:22:02 -0800138typedef struct tcp_iss_seed_
139{
140 u64 first;
141 u64 second;
142} tcp_iss_seed_t;
143
Florin Coras9094b5c2019-08-12 14:17:47 -0700144typedef struct tcp_configuration_
145{
146 /** Max rx fifo size for a session (in bytes). It is used in to compute the
147 * rfc 7323 window scaling factor */
148 u32 max_rx_fifo;
149
150 /** Min rx fifo for a session (in bytes) */
151 u32 min_rx_fifo;
152
153 /** Default MTU to be used when establishing connections */
154 u16 default_mtu;
155
156 /** Initial CWND multiplier, which multiplies MSS to determine initial CWND.
157 * Set 0 to determine the initial CWND by another way */
158 u16 initial_cwnd_multiplier;
159
160 /** Enable tx pacing for new connections */
161 u8 enable_tx_pacing;
162
Florin Corasbbcfaac2019-10-10 13:52:04 -0700163 /** Allow use of TSO whenever available */
164 u8 allow_tso;
165
Florin Corasf4ce6ba2019-11-20 18:34:58 -0800166 /** Set if csum offloading is enabled */
167 u8 csum_offload;
168
Florin Coras9094b5c2019-08-12 14:17:47 -0700169 /** Default congestion control algorithm type */
170 tcp_cc_algorithm_type_e cc_algo;
171
Florin Coras017dc452019-08-30 11:06:35 -0700172 /** Min rwnd, as number of snd_mss segments, for update ack to be sent after
173 * a zero rwnd advertisement */
174 u32 rwnd_min_update_ack;
175
Florin Coras9094b5c2019-08-12 14:17:47 -0700176 /** Timer ticks to wait for close from app */
Ryujiro Shibuya6fa09882020-10-22 05:26:32 +0000177 u32 closewait_time;
Florin Coras9094b5c2019-08-12 14:17:47 -0700178
179 /** Timer ticks to wait in time-wait. Also known as 2MSL */
Ryujiro Shibuya6fa09882020-10-22 05:26:32 +0000180 u32 timewait_time;
Florin Coras9094b5c2019-08-12 14:17:47 -0700181
182 /** Timer ticks to wait in fin-wait1 to send fin and rcv fin-ack */
Ryujiro Shibuya6fa09882020-10-22 05:26:32 +0000183 u32 finwait1_time;
Florin Coras9094b5c2019-08-12 14:17:47 -0700184
185 /** Timer ticks to wait in last ack for ack */
Ryujiro Shibuya6fa09882020-10-22 05:26:32 +0000186 u32 lastack_time;
Florin Coras9094b5c2019-08-12 14:17:47 -0700187
188 /** Timer ticks to wait in fin-wait2 for fin */
Ryujiro Shibuya6fa09882020-10-22 05:26:32 +0000189 u32 finwait2_time;
Florin Coras9094b5c2019-08-12 14:17:47 -0700190
191 /** Timer ticks to wait in closing for fin ack */
Ryujiro Shibuya6fa09882020-10-22 05:26:32 +0000192 u32 closing_time;
Florin Coras9094b5c2019-08-12 14:17:47 -0700193
liuyacan7e781192021-06-14 18:09:01 +0800194 /** Timer ticks to wait for free buffer */
195 u32 alloc_err_timeout;
196
Florin Coras7a3a8662020-02-22 02:27:21 +0000197 /** Time to wait (sec) before cleaning up the connection */
198 f32 cleanup_time;
Florin Coras9094b5c2019-08-12 14:17:47 -0700199
Florin Coras1c30d2d2024-06-10 13:12:40 -0700200 /** Time to wait (tcp ticks) for syn-rcvd connection to establish */
201 u32 syn_rcvd_time;
202
Florin Coras9094b5c2019-08-12 14:17:47 -0700203 /** Number of preallocated connections */
204 u32 preallocated_connections;
205
Simon Zhang23c3d342020-09-15 23:40:28 +0800206 /** Maxium allowed GSO packet size */
207 u32 max_gso_size;
208
Florin Coras9094b5c2019-08-12 14:17:47 -0700209 /** Vectors of src addresses. Optional unless one needs > 63K active-opens */
210 ip4_address_t *ip4_src_addrs;
211 ip6_address_t *ip6_src_addrs;
212
213 /** Fault-injection. Debug only */
214 f64 buffer_fail_fraction;
215} tcp_configuration_t;
216
Dave Barach68b0fb02017-02-28 15:15:56 -0500217typedef struct _tcp_main
218{
Florin Coras04261852020-02-12 01:24:29 +0000219 /** per-worker context */
220 tcp_worker_ctx_t *wrk_ctx;
Dave Barach68b0fb02017-02-28 15:15:56 -0500221
222 /* Pool of listeners. */
223 tcp_connection_t *listener_pool;
224
Florin Corasca031862018-09-24 13:58:05 -0700225 /** vlib buffer size */
226 u32 bytes_per_buffer;
227
Florin Coras04261852020-02-12 01:24:29 +0000228 /** Dispatch table by state and flags */
229 tcp_lookup_dispatch_t dispatch_table[TCP_N_STATES][64];
230
Florin Coras9094b5c2019-08-12 14:17:47 -0700231 /** Seed used to generate random iss */
Florin Coras18e0d4f2019-01-02 12:22:02 -0800232 tcp_iss_seed_t iss_seed;
233
Florin Coras9094b5c2019-08-12 14:17:47 -0700234 /** Congestion control algorithms registered */
Florin Coras4e116fb2019-06-10 08:33:50 -0700235 tcp_cc_algorithm_t *cc_algos;
236
Florin Corasfbf278a2019-03-26 14:05:38 -0700237 /** Hash table of cc algorithms by name */
238 uword *cc_algo_by_name;
239
Florin Coras4e116fb2019-06-10 08:33:50 -0700240 /** Last cc algo registered */
241 tcp_cc_algorithm_type_e cc_last_type;
242
Florin Coras9094b5c2019-08-12 14:17:47 -0700243 /** Flag that indicates if stack is on or off */
Florin Corasa0b34a72017-03-07 01:20:52 -0800244 u8 is_enabled;
245
Florin Coras503480d2023-06-24 18:57:17 -0700246 /** Set if counters on stats segment initialized */
247 u8 counters_init;
248
Florin Coras9094b5c2019-08-12 14:17:47 -0700249 /** Flag that indicates if v4 punting is enabled */
Pierre Pfister7fe51f32017-09-20 08:48:36 +0200250 u8 punt_unknown4;
Florin Coras9094b5c2019-08-12 14:17:47 -0700251
252 /** Flag that indicates if v6 punting is enabled */
Pierre Pfister7fe51f32017-09-20 08:48:36 +0200253 u8 punt_unknown6;
Florin Corasf988e692017-11-27 04:34:14 -0500254
Florin Coras9094b5c2019-08-12 14:17:47 -0700255 /** Rotor for v4 source addresses */
256 u32 last_v4_addr_rotor;
Florin Coras2e31cc32018-09-25 14:00:34 -0700257
Florin Coras9094b5c2019-08-12 14:17:47 -0700258 /** Rotor for v6 source addresses */
259 u32 last_v6_addr_rotor;
260
261 /** Protocol configuration */
262 tcp_configuration_t cfg;
Filip Tehlarec61e102021-06-22 20:39:03 +0000263
264 /** message ID base for API */
265 u16 msg_id_base;
Dave Barach68b0fb02017-02-28 15:15:56 -0500266} tcp_main_t;
267
268extern tcp_main_t tcp_main;
269extern vlib_node_registration_t tcp4_input_node;
270extern vlib_node_registration_t tcp6_input_node;
271extern vlib_node_registration_t tcp4_output_node;
272extern vlib_node_registration_t tcp6_output_node;
Filip Tehlare275bed2019-03-06 00:06:56 -0800273extern vlib_node_registration_t tcp4_established_node;
274extern vlib_node_registration_t tcp6_established_node;
275extern vlib_node_registration_t tcp4_syn_sent_node;
276extern vlib_node_registration_t tcp6_syn_sent_node;
277extern vlib_node_registration_t tcp4_rcv_process_node;
278extern vlib_node_registration_t tcp6_rcv_process_node;
279extern vlib_node_registration_t tcp4_listen_node;
280extern vlib_node_registration_t tcp6_listen_node;
Filip Tehlar5035bf02023-02-20 13:46:32 +0100281extern vlib_node_registration_t tcp4_input_nolookup_node;
282extern vlib_node_registration_t tcp6_input_nolookup_node;
Florin Coras9a1fbb52023-06-08 20:47:11 -0700283extern vlib_node_registration_t tcp4_drop_node;
284extern vlib_node_registration_t tcp6_drop_node;
Dave Barach68b0fb02017-02-28 15:15:56 -0500285
Florin Coras9094b5c2019-08-12 14:17:47 -0700286#define tcp_cfg tcp_main.cfg
Florin Coras1f421012019-07-26 10:18:51 -0700287#define tcp_node_index(node_id, is_ip4) \
288 ((is_ip4) ? tcp4_##node_id##_node.index : tcp6_##node_id##_node.index)
289
Dave Barach68b0fb02017-02-28 15:15:56 -0500290always_inline tcp_main_t *
291vnet_get_tcp_main ()
292{
293 return &tcp_main;
294}
295
Florin Corasbe72ae62018-11-01 11:23:03 -0700296always_inline tcp_worker_ctx_t *
297tcp_get_worker (u32 thread_index)
298{
Florin Coras04261852020-02-12 01:24:29 +0000299 ASSERT (thread_index < vec_len (tcp_main.wrk_ctx));
Florin Corasbe72ae62018-11-01 11:23:03 -0700300 return &tcp_main.wrk_ctx[thread_index];
301}
302
Florin Coras8124cb72018-12-16 20:57:29 -0800303tcp_connection_t *tcp_connection_alloc (u8 thread_index);
Florin Coras12f69362019-08-16 09:44:00 -0700304tcp_connection_t *tcp_connection_alloc_w_base (u8 thread_index,
Florin Coras57b2e4a2021-07-06 08:25:36 -0700305 tcp_connection_t **base);
Florin Coras8124cb72018-12-16 20:57:29 -0800306void tcp_connection_free (tcp_connection_t * tc);
Florin Coras999840c2020-03-18 20:31:34 +0000307void tcp_connection_close (tcp_connection_t * tc);
308void tcp_connection_cleanup (tcp_connection_t * tc);
309void tcp_connection_del (tcp_connection_t * tc);
310int tcp_half_open_connection_cleanup (tcp_connection_t * tc);
Florin Coras3eb50622017-07-13 01:24:57 -0400311
Florin Coras1f152cd2017-08-18 19:28:03 -0700312void tcp_send_reset_w_pkt (tcp_connection_t * tc, vlib_buffer_t * pkt,
Florin Corasd4c49be2019-02-07 00:15:53 -0800313 u32 thread_index, u8 is_ip4);
Florin Coras1f152cd2017-08-18 19:28:03 -0700314void tcp_send_reset (tcp_connection_t * tc);
Dave Barach68b0fb02017-02-28 15:15:56 -0500315void tcp_send_syn (tcp_connection_t * tc);
Florin Coras7ac053b2018-11-05 15:57:21 -0800316void tcp_send_synack (tcp_connection_t * tc);
Dave Barach68b0fb02017-02-28 15:15:56 -0500317void tcp_send_fin (tcp_connection_t * tc);
Florin Corascb711a42019-10-16 19:28:17 -0700318void tcp_send_ack (tcp_connection_t * tc);
Vladimir Kropylev398afbd2019-06-25 00:06:52 +0300319void tcp_send_window_update_ack (tcp_connection_t * tc);
Florin Coras7ac053b2018-11-05 15:57:21 -0800320
Florin Coras26dd6de2019-07-23 23:54:47 -0700321void tcp_program_ack (tcp_connection_t * tc);
322void tcp_program_dupack (tcp_connection_t * tc);
Florin Coras36ebcff2019-09-12 18:36:44 -0700323void tcp_program_retransmit (tcp_connection_t * tc);
Florin Coras26dd6de2019-07-23 23:54:47 -0700324
Florin Coras999840c2020-03-18 20:31:34 +0000325void tcp_update_burst_snd_vars (tcp_connection_t * tc);
Florin Coras45ca73f2018-09-27 09:19:29 -0700326u32 tcp_snd_space (tcp_connection_t * tc);
Florin Corasbe237bf2019-09-27 08:16:40 -0700327int tcp_fastrecovery_prr_snd_space (tcp_connection_t * tc);
Florin Coras6080e0d2020-03-13 20:39:43 +0000328void tcp_reschedule (tcp_connection_t * tc);
Florin Corasf6359c82017-06-19 12:26:09 -0400329fib_node_index_t tcp_lookup_rmt_in_fib (tcp_connection_t * tc);
Florin Corasf66cc802021-04-08 19:10:07 -0700330u32 tcp_session_push_header (transport_connection_t *tconn, vlib_buffer_t **b,
331 u32 n_bufs);
Florin Coras9f86d222020-03-23 15:34:22 +0000332int tcp_session_custom_tx (void *conn, transport_send_params_t * sp);
Dave Barach68b0fb02017-02-28 15:15:56 -0500333
334void tcp_connection_timers_init (tcp_connection_t * tc);
335void tcp_connection_timers_reset (tcp_connection_t * tc);
Florin Coras4eeeaaf2017-09-05 14:03:37 -0400336void tcp_init_snd_vars (tcp_connection_t * tc);
Dave Barach68b0fb02017-02-28 15:15:56 -0500337void tcp_connection_init_vars (tcp_connection_t * tc);
Florin Corasc44a5582018-11-01 16:30:54 -0700338void tcp_connection_tx_pacer_update (tcp_connection_t * tc);
339void tcp_connection_tx_pacer_reset (tcp_connection_t * tc, u32 window,
340 u32 start_bucket);
Florin Coras7a3a8662020-02-22 02:27:21 +0000341void tcp_program_cleanup (tcp_worker_ctx_t * wrk, tcp_connection_t * tc);
Florin Coras04ae8272021-04-12 19:55:37 -0700342void tcp_check_gso (tcp_connection_t *tc);
Florin Corasd67f1122018-05-21 17:47:40 -0700343
Florin Coras505fd372021-11-02 17:13:15 -0700344int tcp_buffer_make_reset (vlib_main_t *vm, vlib_buffer_t *b, u8 is_ip4);
Florin Coras999840c2020-03-18 20:31:34 +0000345void tcp_punt_unknown (vlib_main_t * vm, u8 is_ip4, u8 is_add);
346int tcp_configure_v4_source_address_range (vlib_main_t * vm,
347 ip4_address_t * start,
348 ip4_address_t * end, u32 table_id);
349int tcp_configure_v6_source_address_range (vlib_main_t * vm,
350 ip6_address_t * start,
351 ip6_address_t * end, u32 table_id);
Dave Barach68b0fb02017-02-28 15:15:56 -0500352
Florin Coras999840c2020-03-18 20:31:34 +0000353clib_error_t *vnet_tcp_enable_disable (vlib_main_t * vm, u8 is_en);
Florin Coras52814732019-06-12 15:38:19 -0700354
Florin Coras999840c2020-03-18 20:31:34 +0000355format_function_t format_tcp_state;
356format_function_t format_tcp_flags;
357format_function_t format_tcp_sacks;
358format_function_t format_tcp_rcv_sacks;
359format_function_t format_tcp_connection;
Aritra Basue30f7122024-07-26 09:36:55 -0700360format_function_t format_tcp_listener_connection;
Florin Coras999840c2020-03-18 20:31:34 +0000361format_function_t format_tcp_connection_id;
Florin Corasd2067242019-08-16 10:33:49 -0700362
Florin Coras93992a92017-05-24 18:03:56 -0700363#define tcp_validate_txf_size(_tc, _a) \
364 ASSERT(_tc->state != TCP_STATE_ESTABLISHED \
Florin Coras31c99552019-03-01 13:00:58 -0800365 || transport_max_tx_dequeue (&_tc->connection) >= _a)
Florin Coras93992a92017-05-24 18:03:56 -0700366
Dave Barach68b0fb02017-02-28 15:15:56 -0500367#endif /* _vnet_tcp_h_ */
368
369/*
370 * fd.io coding-style-patch-verification: ON
371 *
372 * Local Variables:
373 * eval: (c-set-style "gnu")
374 * End:
375 */