16 #ifndef SRC_VNET_TCP_TCP_INLINES_H_ 17 #define SRC_VNET_TCP_TCP_INLINES_H_ 54 TCP_EVT (TCP_EVT_STATE_CHANGE, tc);
84 return tc->sack_sb.sacked_bytes + tc->sack_sb.lost_bytes;
86 return clib_min (tc->rcv_dupacks * tc->snd_mss,
87 tc->snd_nxt - tc->snd_una);
98 flight_size = (int) (tc->snd_nxt - tc->snd_una) -
tcp_bytes_out (tc)
99 + tc->snd_rxt_bytes - tc->rxt_delivered;
101 ASSERT (flight_size >= 0);
112 if (
tcp_cfg.initial_cwnd_multiplier > 0)
113 return tcp_cfg.initial_cwnd_multiplier * tc->snd_mss;
115 if (tc->snd_mss > 2190)
116 return 2 * tc->snd_mss;
117 else if (tc->snd_mss > 1095)
118 return 3 * tc->snd_mss;
120 return 4 * tc->snd_mss;
132 tc->cwnd_acc_bytes += bytes;
133 if (tc->cwnd_acc_bytes >= thresh)
135 u32 inc = tc->cwnd_acc_bytes / thresh;
136 tc->cwnd_acc_bytes -= inc * thresh;
137 tc->cwnd += inc * tc->snd_mss;
138 tc->cwnd =
clib_min (tc->cwnd, tc->tx_fifo_size);
152 return clib_min (tc->cwnd, tc->snd_wnd);
159 int flight_size = (int) (tc->snd_nxt - tc->snd_una);
161 if (available_wnd <= flight_size)
164 return available_wnd - flight_size;
176 if (available_wnd <= flight_size)
179 return available_wnd - flight_size;
185 if ((tc->flags & TCP_CONN_FINSNT) && (tc->snd_nxt - tc->snd_una == 1))
199 return tcp_main.wrk_ctx[thread_index].time_now;
208 return (
tcp_main.wrk_ctx[tc->c_thread_index].time_now -
209 tc->timestamp_delta);
226 u8 is_ip4,
u8 is_nolookup)
229 int n_advance_bytes, n_data_bytes;
240 *error = TCP_ERROR_LENGTH;
246 n_data_bytes = clib_net_to_host_u16 (ip4->
length) - n_advance_bytes;
251 *error = TCP_ERROR_LENGTH;
259 TRANSPORT_PROTO_TCP, thread_index,
267 *error = TCP_ERROR_LENGTH;
275 n_advance_bytes +=
sizeof (ip6[0]);
279 *error = TCP_ERROR_LENGTH;
295 tcp->dst_port, tcp->src_port,
297 thread_index, &result);
304 tcp.connection_index,
307 vnet_buffer (b)->tcp.seq_number = clib_net_to_host_u32 (tcp->seq_number);
308 vnet_buffer (b)->tcp.ack_number = clib_net_to_host_u32 (tcp->ack_number);
309 vnet_buffer (b)->tcp.data_offset = n_advance_bytes;
315 *error = result ? TCP_ERROR_NONE + result : *error;
332 tc->c_lcl_port = th->dst_port;
333 tc->c_rmt_port = th->src_port;
334 tc->c_is_ip4 = is_ip4;
346 sizeof (ip6_address_t));
348 sizeof (ip6_address_t));
353 tc->rcv_las = tc->rcv_nxt;
362 tc->tsval_recent = tc->rcv_opts.tsval;
367 tc->snd_wscale = tc->rcv_opts.wscale;
369 tc->snd_wnd = clib_net_to_host_u16 (th->window) << tc->snd_wscale;
411 th->seq_number = seq;
412 th->ack_number = ack;
413 th->data_offset_and_reserved = (tcp_hdr_opts_len >> 2) << 4;
417 th->urgent_pointer = 0;
419 b->
flags |= VNET_BUFFER_F_L4_HDR_OFFSET_VALID;
442 clib_host_to_net_u32 (seq),
443 clib_host_to_net_u32 (ack),
444 tcp_hdr_opts_len, flags,
445 clib_host_to_net_u16 (wnd));
static void tcp_cwnd_accumulate(tcp_connection_t *tc, u32 thresh, u32 bytes)
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
static u32 tcp_loss_wnd(const tcp_connection_t *tc)
static clib_time_type_t transport_time_now(u32 thread_index)
static u32 tcp_time_now(void)
vl_api_wireguard_peer_flags_t flags
static tcp_connection_t * tcp_connection_get(u32 conn_index, u32 thread_index)
transport_connection_t * session_lookup_connection_wt6(u32 fib_index, ip6_address_t *lcl, ip6_address_t *rmt, u16 lcl_port, u16 rmt_port, u8 proto, u32 thread_index, u8 *result)
Lookup connection with ip6 and transport layer information.
#define tcp_opts_tstamp(_to)
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
#define clib_memcpy_fast(a, b, c)
static f64 vlib_time_now(vlib_main_t *vm)
#define VLIB_BUFFER_PRE_DATA_SIZE
static_always_inline void clib_spinlock_unlock_if_init(clib_spinlock_t *p)
static void * vlib_buffer_push_tcp_net_order(vlib_buffer_t *b, u16 sp, u16 dp, u32 seq, u32 ack, u8 tcp_hdr_opts_len, u8 flags, u16 wnd)
Push TCP header to buffer.
u16 current_length
Nbytes between current data and the end of this buffer.
struct _tcp_connection tcp_connection_t
static u32 tcp_set_time_now(tcp_worker_ctx_t *wrk)
static u32 tcp_time_now_w_thread(u32 thread_index)
static u8 tcp_is_descheduled(tcp_connection_t *tc)
struct _tcp_header tcp_header_t
tcp_connection_t * connections
worker's pool of connections
transport_connection_t * session_lookup_connection_wt4(u32 fib_index, ip4_address_t *lcl, ip4_address_t *rmt, u16 lcl_port, u16 rmt_port, u8 proto, u32 thread_index, u8 *result)
Lookup connection with ip4 and transport layer information.
static void * ip4_next_header(ip4_header_t *i)
static tcp_header_t * tcp_buffer_hdr(vlib_buffer_t *b)
vlib_main_t * vm
convenience pointer to this thread's vlib main
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
static tcp_connection_t * tcp_half_open_connection_get(u32 conn_index)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
static u32 tcp_initial_cwnd(const tcp_connection_t *tc)
Initial cwnd as per RFC5681.
static u8 tcp_is_lost_fin(tcp_connection_t *tc)
static u32 tcp_available_output_snd_space(const tcp_connection_t *tc)
static u32 tcp_flight_size(const tcp_connection_t *tc)
Our estimate of the number of bytes in flight (pipe size)
static_always_inline uword vlib_get_thread_index(void)
static void tcp_update_rto(tcp_connection_t *tc)
struct _transport_connection transport_connection_t
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
#define TCP_TSTP_HZ
Timestamp freq.
static u32 tcp_available_cc_snd_space(const tcp_connection_t *tc)
Estimate of how many bytes we can still push into the network.
static void * ip6_next_header(ip6_header_t *i)
static void * vlib_buffer_push_tcp(vlib_buffer_t *b, u16 sp_net, u16 dp_net, u32 seq, u32 ack, u8 tcp_hdr_opts_len, u8 flags, u16 wnd)
Push TCP header to buffer.
static tcp_connection_t * tcp_connection_get_if_valid(u32 conn_index, u32 thread_index)
static uword ip6_address_is_link_local_unicast(const ip6_address_t *a)
#define vec_elt(v, i)
Get vector value at index i.
#define tcp_opts_wscale(_to)
static void * vlib_buffer_push_uninit(vlib_buffer_t *b, u8 size)
Prepend uninitialized data to buffer.
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static tcp_connection_t * tcp_listener_get(u32 tli)
static tcp_worker_ctx_t * tcp_get_worker(u32 thread_index)
VLIB buffer representation.
u32 time_now
Time measured in TCP_TSTAMP_TICK used for time stamps.
static void tcp_init_w_buffer(tcp_connection_t *tc, vlib_buffer_t *b, u8 is_ip4)
Initialize connection by gleaning network and rcv params from buffer.
static f64 tcp_time_now_us(u32 thread_index)
static void tcp_connection_set_state(tcp_connection_t *tc, tcp_state_t state)
static u32 tcp_bytes_out(const tcp_connection_t *tc)
Our estimate of the number of bytes that have left the network.
static u32 tcp_available_snd_wnd(const tcp_connection_t *tc)
static int tcp_header_bytes(tcp_header_t *t)
vl_api_dhcp_client_state_t state
#define tcp_opts_sack_permitted(_to)
static u32 tcp_tstamp(tcp_connection_t *tc)
Generate timestamp for tcp connection.
static int ip4_header_bytes(const ip4_header_t *i)
static tcp_connection_t * tcp_get_connection_from_transport(transport_connection_t *tconn)
static_always_inline void clib_spinlock_lock_if_init(clib_spinlock_t *p)
u32 * fib_index_by_sw_if_index
static tcp_connection_t * tcp_input_lookup_buffer(vlib_buffer_t *b, u8 thread_index, u32 *error, u8 is_ip4, u8 is_nolookup)
enum _tcp_state tcp_state_t
vl_api_interface_index_t sw_if_index
#define TCP_EVT(_evt, _args...)
static u8 transport_connection_is_descheduled(transport_connection_t *tc)