25 u16 port_host_byte_order,
u8 is_ip4)
30 pool_get (tm->listener_pool, listener);
31 memset (listener, 0,
sizeof (*listener));
33 listener->c_c_index = listener - tm->listener_pool;
34 listener->c_lcl_port = clib_host_to_net_u16 (port_host_byte_order);
37 listener->c_lcl_ip4.as_u32 = ip->ip4.as_u32;
41 listener->c_s_index = session_index;
42 listener->c_proto = SESSION_TYPE_IP4_TCP;
43 listener->state = TCP_STATE_LISTEN;
44 listener->c_is_ip4 = 1;
50 return listener->c_c_index;
55 u16 port_host_byte_order)
62 u16 port_host_byte_order)
90 return &tc->connection;
114 pool_put (tm->local_endpoints, tep);
121 if (tc->state == TCP_STATE_SYN_SENT)
122 pool_put (tm->half_open_connections, tc);
124 pool_put (tm->connections[tc->c_thread_index], tc);
149 if (tc->state == TCP_STATE_CLOSED)
152 tc->state = TCP_STATE_CLOSED;
175 if (tc->state == TCP_STATE_ESTABLISHED || tc->state == TCP_STATE_SYN_RCVD
176 || tc->state == TCP_STATE_CLOSE_WAIT)
180 if (tc->state == TCP_STATE_ESTABLISHED || tc->state == TCP_STATE_SYN_RCVD)
181 tc->state = TCP_STATE_FIN_WAIT_1;
182 else if (tc->state == TCP_STATE_SYN_SENT)
183 tc->state = TCP_STATE_CLOSED;
184 else if (tc->state == TCP_STATE_CLOSE_WAIT)
185 tc->state = TCP_STATE_LAST_ACK;
189 && tc->state == TCP_STATE_CLOSED)
208 tc->state = TCP_STATE_CLOSED;
241 #define PORT_MASK ((1 << 16)- 1) 251 u16 min = 1024, max = 65535;
258 pool_get (tm->local_endpoints, tep);
262 for (; tries >= 0; tries--)
283 tep - tm->local_endpoints);
288 pool_put (tm->local_endpoints, tep);
341 u32 fei, sw_if_index;
342 ip46_address_t lcl_addr;
348 memset (&lcl_addr, 0,
sizeof (lcl_addr));
353 prefix.
fp_len = is_ip4 ? 32 : 128;
363 if (sw_if_index == (
u32) ~ 0)
370 lcl_addr.ip4.as_u32 = ip4->
as_u32;
391 pool_get (tm->half_open_connections, tc);
392 memset (tc, 0,
sizeof (*tc));
394 clib_memcpy (&tc->c_rmt_ip, rmt_addr, sizeof (ip46_address_t));
395 clib_memcpy (&tc->c_lcl_ip, &lcl_addr, sizeof (ip46_address_t));
396 tc->c_rmt_port = clib_host_to_net_u16 (rmt_port);
397 tc->c_lcl_port = clib_host_to_net_u16 (lcl_port);
398 tc->c_c_index = tc - tm->half_open_connections;
399 tc->c_is_ip4 = is_ip4;
406 tc->state = TCP_STATE_SYN_SENT;
410 return tc->c_c_index;
426 #define _(sym, str) str, 432 #define _(sym, str) str, 445 s =
format (s,
"UNKNOWN");
451 #define _(sym, str) str, 467 for (i = 0; i <
last; i++)
488 s =
format (s,
"[#%d][%s] %U:%d->%U:%d", tc->c_thread_index,
"T",
491 &tc->c_rmt_ip4, clib_net_to_host_u16 (tc->c_rmt_port));
495 s =
format (s,
"[#%d][%s] %U:%d->%U:%d", tc->c_thread_index,
"T",
498 &tc->c_rmt_ip6, clib_net_to_host_u16 (tc->c_rmt_port));
516 u32 tci = va_arg (*args,
u32);
517 u32 thread_index = va_arg (*args,
u32);
527 u32 tci = va_arg (*args,
u32);
535 u32 tci = va_arg (*args,
u32);
544 return &tc->connection;
551 return &tc->connection;
572 return (tc->snd_nxt - tc->snd_una);
634 ASSERT (tc->state == TCP_STATE_SYN_SENT);
636 sst = tc->c_is_ip4 ? SESSION_TYPE_IP4_TCP : SESSION_TYPE_IP6_TCP;
653 if (tc->state == TCP_STATE_CLOSE_WAIT)
655 if (tc->flags & TCP_CONN_FINSNT)
657 clib_warning (
"FIN was sent and still in CLOSE WAIT. Weird!");
661 tc->state = TCP_STATE_LAST_ACK;
690 u32 connection_index, timer_id;
692 for (i = 0; i <
vec_len (expired_timers); i++)
695 connection_index = expired_timers[
i] & 0x0FFFFFFF;
696 timer_id = expired_timers[
i] >> 28;
698 TCP_EVT_DBG (TCP_EVT_TIMER_POP, connection_index, timer_id);
708 tw_timer_wheel_16t_2w_512sl_t *tw;
772 clib_bihash_init_24_8 (&tm->local_endpoints_table,
"local endpoint table",
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
#define foreach_ip_interface_address(lm, a, sw_if_index, loop, body)
fib_protocol_t fp_proto
protocol type
void tcp_timer_keep_handler(u32 conn_index)
sll srl srl sll sra u16x4 i
const char * tcp_fsm_states[]
void * ip_interface_get_first_ip(u32 sw_if_index, u8 is_ip4)
void stream_session_connect_notify(transport_connection_t *tc, u8 sst, u8 is_fail)
vnet_main_t * vnet_get_main(void)
struct _transport_connection transport_connection_t
u32 tcp_session_unbind(u32 listener_index)
static f64 vlib_time_now(vlib_main_t *vm)
static tcp_connection_t * tcp_half_open_connection_get(u32 conn_index)
struct _tcp_main tcp_main_t
void tcp_connection_timers_reset(tcp_connection_t *tc)
Stop all connection timers.
timer_expiration_handler tcp_timer_retransmit_handler
static heap_elt_t * last(heap_header_t *h)
ip_lookup_main_t lookup_main
struct _tcp_connection tcp_connection_t
transport_connection_t * tcp_half_open_session_get_transport(u32 conn_index)
u16 tcp_allocate_local_port(tcp_main_t *tm, ip46_address_t *ip)
Allocate local port and add if successful add entry to local endpoint table to mark the pair as used...
void tcp_timer_establish_handler(u32 conn_index)
void ip4_register_protocol(u32 protocol, u32 node_index)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
static u32 tcp_available_snd_space(const tcp_connection_t *tc)
u32 tcp_session_tx_fifo_offset(transport_connection_t *trans_conn)
unformat_function_t * unformat_pg_edit
#define VLIB_INIT_FUNCTION(x)
void tcp_connection_timers_init(tcp_connection_t *tc)
Initialize all connection timers as invalid.
void transport_endpoint_table_del(transport_endpoint_table_t *ht, transport_endpoint_t *te)
static void tcp_connection_unbind(u32 listener_index)
clib_error_t * tcp_main_enable(vlib_main_t *vm)
Aggregrate type for a prefix.
enum _tcp_state tcp_state_t
#define clib_error_return(e, args...)
void stream_session_delete_notify(transport_connection_t *tc)
Notification from transport that connection is being deleted.
timer_expiration_handler tcp_timer_retransmit_syn_handler
static u32 tcp_time_now(void)
u16 fp_len
The mask length.
#define vlib_call_init_function(vm, x)
u32 tcp_session_bind_ip4(u32 session_index, ip46_address_t *ip, u16 port_host_byte_order)
#define TCP_EVT_DBG(_evt, _args...)
fib_node_index_t fib_table_lookup(u32 fib_index, const fib_prefix_t *prefix)
Perfom a longest prefix match in the non-forwarding table.
u8 * format_tcp_connection_verbose(u8 *s, va_list *args)
struct _transport_proto_vft transport_proto_vft_t
#define TRANSPORT_ENDPOINT_INVALID_INDEX
static void tcp_timer_set(tcp_connection_t *tc, u8 timer_id, u32 interval)
static timer_expiration_handler * timer_expiration_handlers[TCP_N_TIMERS]
#define TCP_INVALID_SACK_HOLE_INDEX
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
transport_connection_t * tcp_session_get_listener(u32 listener_index)
static ip_protocol_info_t * ip_get_protocol_info(ip_main_t *im, u32 protocol)
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
format_function_t * format_header
void tcp_session_cleanup(u32 conn_index, u32 thread_index)
void tcp_send_syn(tcp_connection_t *tc)
Send SYN.
uword os_get_cpu_number(void)
static const transport_proto_vft_t tcp4_proto
#define pool_put(P, E)
Free an object E in pool P.
static void tcp_expired_timers_dispatch(u32 *expired_timers)
#define TCP_TIMER_HANDLE_INVALID
void tcp_timer_waitclose_handler(u32 conn_index)
clib_error_t * vnet_tcp_enable_disable(vlib_main_t *vm, u8 is_en)
u32 tcp_push_header(transport_connection_t *tconn, vlib_buffer_t *b)
void transport_endpoint_table_add(transport_endpoint_table_t *ht, transport_endpoint_t *te, u32 value)
void tcp_session_close(u32 conn_index, u32 thread_index)
void( timer_expiration_handler)(u32 index)
static u32 tcp_connection_bind(u32 session_index, ip46_address_t *ip, u16 port_host_byte_order, u8 is_ip4)
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
static void tcp_timer_reset(tcp_connection_t *tc, u8 timer_id)
u8 * format_tcp_half_open_session(u8 *s, va_list *args)
clib_error_t * ip_main_init(vlib_main_t *vm)
void tcp_cc_init(tcp_connection_t *tc)
void tcp_connection_close(tcp_connection_t *tc)
Begin connection closing procedure.
void tcp_set_snd_mss(tcp_connection_t *tc)
#define clib_warning(format, args...)
#define clib_memcpy(a, b, c)
u8 * format_tcp_session(u8 *s, va_list *args)
int tcp_session_open_ip6(ip46_address_t *addr, u16 port)
const char * tcp_dbg_evt_str[]
int tcp_connection_open(ip46_address_t *rmt_addr, u16 rmt_port, u8 is_ip4)
u16 tcp_session_send_mss(transport_connection_t *trans_conn)
static void tcp_timer_update(tcp_connection_t *tc, u8 timer_id, u32 interval)
#define pool_put_index(p, i)
Free pool element with given index.
ip_lookup_main_t lookup_main
vhost_vring_state_t state
u32 transport_endpoint_lookup(transport_endpoint_table_t *ht, ip46_address_t *ip, u16 port)
void stream_session_reset_notify(transport_connection_t *tc)
Notify application that connection has been reset.
clib_error_t * ip4_lookup_init(vlib_main_t *vm)
void session_register_transport(u8 type, const transport_proto_vft_t *vft)
u8 * format_tcp_timers(u8 *s, va_list *args)
void tcp_connection_reset(tcp_connection_t *tc)
Notify session that connection has been reset.
vlib_node_registration_t tcp4_input_node
(constructor) VLIB_REGISTER_NODE (tcp4_input_node)
#define FIB_NODE_INDEX_INVALID
int tcp_session_open_ip4(ip46_address_t *addr, u16 port)
#define foreach_tcp_fsm_state
TCP FSM state definitions as per RFC793.
void tcp_send_fin(tcp_connection_t *tc)
Send FIN.
#define foreach_tcp_timer
TCP timers.
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
struct _transport_endpoint transport_endpoint_t
void tcp_connection_init_vars(tcp_connection_t *tc)
Initialize tcp connection variables.
const char * tcp_conn_timers[]
clib_error_t * tcp_init(vlib_main_t *vm)
u8 * format_tcp_connection(u8 *s, va_list *args)
static tcp_connection_t * tcp_connection_get(u32 conn_index, u32 thread_index)
static u32 random_u32(u32 *seed)
32-bit random number generator
ip4_main_t ip4_main
Global ip4 main structure.
static vlib_thread_main_t * vlib_get_thread_main()
void tcp_connection_cleanup(tcp_connection_t *tc)
Cleans up connection state.
void tcp_connection_del(tcp_connection_t *tc)
Connection removal.
#define vec_foreach(var, vec)
Vector iterator.
#define TCP_TSTAMP_RESOLUTION
Time stamp resolution.
static void * ip_interface_address_get_address(ip_lookup_main_t *lm, ip_interface_address_t *a)
static const transport_proto_vft_t tcp6_proto
u8 * format_tcp_state(u8 *s, va_list *args)
u32 tcp_session_send_space(transport_connection_t *trans_conn)
static clib_error_t * ip6_lookup_init(vlib_main_t *vm)
static tcp_main_t * vnet_get_tcp_main()
timer_expiration_handler tcp_timer_delack_handler
u32 tcp_session_bind_ip6(u32 session_index, ip46_address_t *ip, u16 port_host_byte_order)
transport_connection_t * tcp_session_get_transport(u32 conn_index, u32 thread_index)
u8 * format_tcp_listener_session(u8 *s, va_list *args)
void tcp_initialize_timer_wheels(tcp_main_t *tm)
static tcp_connection_t * tcp_listener_get(u32 tli)