diff options
Diffstat (limited to 'src/vnet/tcp')
-rw-r--r-- | src/vnet/tcp/tcp.c | 122 | ||||
-rw-r--r-- | src/vnet/tcp/tcp_input.c | 5 |
2 files changed, 55 insertions, 72 deletions
diff --git a/src/vnet/tcp/tcp.c b/src/vnet/tcp/tcp.c index a2214158c1b..6d1cfa07749 100644 --- a/src/vnet/tcp/tcp.c +++ b/src/vnet/tcp/tcp.c @@ -22,8 +22,7 @@ tcp_main_t tcp_main; static u32 -tcp_connection_bind (u32 session_index, ip46_address_t * ip, - u16 port_host_byte_order, u8 is_ip4) +tcp_connection_bind (u32 session_index, transport_endpoint_t * lcl) { tcp_main_t *tm = &tcp_main; tcp_connection_t *listener; @@ -32,17 +31,18 @@ tcp_connection_bind (u32 session_index, ip46_address_t * ip, memset (listener, 0, sizeof (*listener)); listener->c_c_index = listener - tm->listener_pool; - listener->c_lcl_port = clib_host_to_net_u16 (port_host_byte_order); + listener->c_lcl_port = clib_host_to_net_u16 (lcl->port); - if (is_ip4) + if (lcl->is_ip4) { - listener->c_lcl_ip4.as_u32 = ip->ip4.as_u32; + listener->c_lcl_ip4.as_u32 = lcl->ip.ip4.as_u32; listener->c_is_ip4 = 1; listener->c_proto = SESSION_TYPE_IP4_TCP; } else { - clib_memcpy (&listener->c_lcl_ip6, &ip->ip6, sizeof (ip6_address_t)); + clib_memcpy (&listener->c_lcl_ip6, &lcl->ip.ip6, + sizeof (ip6_address_t)); listener->c_proto = SESSION_TYPE_IP6_TCP; } @@ -57,17 +57,9 @@ tcp_connection_bind (u32 session_index, ip46_address_t * ip, } u32 -tcp_session_bind_ip4 (u32 session_index, ip46_address_t * ip, - u16 port_host_byte_order) -{ - return tcp_connection_bind (session_index, ip, port_host_byte_order, 1); -} - -u32 -tcp_session_bind_ip6 (u32 session_index, ip46_address_t * ip, - u16 port_host_byte_order) +tcp_session_bind (u32 session_index, transport_endpoint_t * tep) { - return tcp_connection_bind (session_index, ip, port_host_byte_order, 0); + return tcp_connection_bind (session_index, tep); } static void @@ -133,10 +125,7 @@ tcp_connection_cleanup (tcp_connection_t * tc) /* Check if half-open */ if (tc->state == TCP_STATE_SYN_SENT) { - /* Poison the entry */ - if (CLIB_DEBUG > 0) - memset (tc, 0xFA, sizeof (*tc)); - pool_put (tm->half_open_connections, tc); + tcp_half_open_connection_del (tc); } else { @@ -172,9 +161,21 @@ tcp_half_open_connection_del (tcp_connection_t * tc) tcp_main_t *tm = vnet_get_tcp_main (); if (CLIB_DEBUG) memset (tc, 0xFA, sizeof (*tc)); - clib_spinlock_lock (&tm->half_open_lock); + clib_spinlock_lock_if_init (&tm->half_open_lock); pool_put (tm->half_open_connections, tc); - clib_spinlock_unlock (&tm->half_open_lock); + clib_spinlock_unlock_if_init (&tm->half_open_lock); +} + +tcp_connection_t * +tcp_half_open_connection_new () +{ + tcp_main_t *tm = vnet_get_tcp_main (); + tcp_connection_t *tc = 0; + clib_spinlock_lock_if_init (&tm->half_open_lock); + pool_get (tm->half_open_connections, tc); + clib_spinlock_unlock_if_init (&tm->half_open_lock); + memset (tc, 0, sizeof (*tc)); + return tc; } tcp_connection_t * @@ -456,11 +457,13 @@ fib_node_index_t tcp_lookup_rmt_in_fib (tcp_connection_t * tc) { fib_prefix_t prefix; + u32 fib_index; clib_memcpy (&prefix.fp_addr, &tc->c_rmt_ip, sizeof (prefix.fp_addr)); prefix.fp_proto = tc->c_is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6; prefix.fp_len = tc->c_is_ip4 ? 32 : 128; - return fib_table_lookup (0, &prefix); + fib_index = fib_table_find (prefix.fp_proto, tc->c_vrf); + return fib_table_lookup (fib_index, &prefix); } static int @@ -512,13 +515,13 @@ tcp_connection_init_vars (tcp_connection_t * tc) } int -tcp_connection_open (ip46_address_t * rmt_addr, u16 rmt_port, u8 is_ip4) +tcp_connection_open (transport_endpoint_t * rmt) { tcp_main_t *tm = vnet_get_tcp_main (); tcp_connection_t *tc; fib_prefix_t prefix; fib_node_index_t fei; - u32 sw_if_index; + u32 sw_if_index, fib_index; ip46_address_t lcl_addr; int lcl_port; @@ -528,11 +531,12 @@ tcp_connection_open (ip46_address_t * rmt_addr, u16 rmt_port, u8 is_ip4) memset (&lcl_addr, 0, sizeof (lcl_addr)); /* Find a FIB path to the destination */ - clib_memcpy (&prefix.fp_addr, rmt_addr, sizeof (*rmt_addr)); - prefix.fp_proto = is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6; - prefix.fp_len = is_ip4 ? 32 : 128; + clib_memcpy (&prefix.fp_addr, &rmt->ip, sizeof (rmt->ip)); + prefix.fp_proto = rmt->is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6; + prefix.fp_len = rmt->is_ip4 ? 32 : 128; - fei = fib_table_lookup (0, &prefix); + fib_index = fib_table_find (prefix.fp_proto, rmt->vrf); + fei = fib_table_lookup (fib_index, &prefix); /* Couldn't find route to destination. Bail out. */ if (fei == FIB_NODE_INDEX_INVALID) @@ -546,11 +550,11 @@ tcp_connection_open (ip46_address_t * rmt_addr, u16 rmt_port, u8 is_ip4) if (sw_if_index == (u32) ~ 0) { clib_warning ("no resolving interface for %U", format_ip46_address, - rmt_addr, IP46_TYPE_IP4); + &rmt->ip, IP46_TYPE_IP4); return -1; } - if (is_ip4) + if (rmt->is_ip4) { ip4_address_t *ip4; int index; @@ -599,17 +603,16 @@ tcp_connection_open (ip46_address_t * rmt_addr, u16 rmt_port, u8 is_ip4) * Create connection and send SYN */ - pool_get (tm->half_open_connections, tc); - memset (tc, 0, sizeof (*tc)); + tc = tcp_half_open_connection_new (); - clib_memcpy (&tc->c_rmt_ip, rmt_addr, sizeof (ip46_address_t)); + clib_memcpy (&tc->c_rmt_ip, &rmt->ip, sizeof (ip46_address_t)); clib_memcpy (&tc->c_lcl_ip, &lcl_addr, sizeof (ip46_address_t)); - tc->c_rmt_port = clib_host_to_net_u16 (rmt_port); + tc->c_rmt_port = clib_host_to_net_u16 (rmt->port); tc->c_lcl_port = clib_host_to_net_u16 (lcl_port); tc->c_c_index = tc - tm->half_open_connections; - tc->c_is_ip4 = is_ip4; - tc->c_proto = is_ip4 ? SESSION_TYPE_IP4_TCP : SESSION_TYPE_IP6_TCP; - + tc->c_is_ip4 = rmt->is_ip4; + tc->c_proto = rmt->is_ip4 ? SESSION_TYPE_IP4_TCP : SESSION_TYPE_IP6_TCP; + tc->c_vrf = rmt->vrf; /* The other connection vars will be initialized after SYN ACK */ tcp_connection_timers_init (tc); @@ -621,15 +624,9 @@ tcp_connection_open (ip46_address_t * rmt_addr, u16 rmt_port, u8 is_ip4) } int -tcp_session_open_ip4 (ip46_address_t * addr, u16 port) -{ - return tcp_connection_open (addr, port, 1); -} - -int -tcp_session_open_ip6 (ip46_address_t * addr, u16 port) +tcp_session_open (transport_endpoint_t * tep) { - return tcp_connection_open (addr, port, 0); + return tcp_connection_open (tep); } const char *tcp_dbg_evt_str[] = { @@ -1025,32 +1022,14 @@ tcp_session_tx_fifo_offset (transport_connection_t * trans_conn) } /* *INDENT-OFF* */ -const static transport_proto_vft_t tcp4_proto = { - .bind = tcp_session_bind_ip4, - .unbind = tcp_session_unbind, - .push_header = tcp_push_header, - .get_connection = tcp_session_get_transport, - .get_listener = tcp_session_get_listener, - .get_half_open = tcp_half_open_session_get_transport, - .open = tcp_session_open_ip4, - .close = tcp_session_close, - .cleanup = tcp_session_cleanup, - .send_mss = tcp_session_send_mss, - .send_space = tcp_session_send_space, - .tx_fifo_offset = tcp_session_tx_fifo_offset, - .format_connection = format_tcp_session, - .format_listener = format_tcp_listener_session, - .format_half_open = format_tcp_half_open_session, -}; - -const static transport_proto_vft_t tcp6_proto = { - .bind = tcp_session_bind_ip6, +const static transport_proto_vft_t tcp_proto = { + .bind = tcp_session_bind, .unbind = tcp_session_unbind, .push_header = tcp_push_header, .get_connection = tcp_session_get_transport, .get_listener = tcp_session_get_listener, .get_half_open = tcp_half_open_session_get_transport, - .open = tcp_session_open_ip6, + .open = tcp_session_open, .close = tcp_session_close, .cleanup = tcp_session_cleanup, .send_mss = tcp_session_send_mss, @@ -1200,9 +1179,9 @@ tcp_main_enable (vlib_main_t * vm) ip4_register_protocol (IP_PROTOCOL_TCP, tcp4_input_node.index); - /* Register as transport with URI */ - session_register_transport (SESSION_TYPE_IP4_TCP, &tcp4_proto); - session_register_transport (SESSION_TYPE_IP6_TCP, &tcp6_proto); + /* Register as transport with session layer */ + session_register_transport (SESSION_TYPE_IP4_TCP, &tcp_proto); + session_register_transport (SESSION_TYPE_IP6_TCP, &tcp_proto); /* * Initialize data structures @@ -1247,7 +1226,8 @@ tcp_main_enable (vlib_main_t * vm) clib_bihash_init_24_8 (&tm->local_endpoints_table, "local endpoint table", 200000 /* $$$$ config parameter nbuckets */ , (64 << 20) /*$$$ config parameter table size */ ); - clib_spinlock_init (&tm->half_open_lock); + if (num_threads > 1) + clib_spinlock_init (&tm->half_open_lock); return error; } diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c index cc5cecdc473..d32b4fc89a5 100644 --- a/src/vnet/tcp/tcp_input.c +++ b/src/vnet/tcp/tcp_input.c @@ -2742,7 +2742,10 @@ tcp_lookup_is_valid (tcp_connection_t * tc, tcp_header_t * hdr) if (!is_valid) { - if ((tmp = stream_session_lookup_half_open (&tc->connection))) + if ((tmp = + stream_session_half_open_lookup (&tc->c_lcl_ip, &tc->c_rmt_ip, + tc->c_lcl_port, tc->c_rmt_port, + tc->c_proto))) { if (tmp->lcl_port == hdr->dst_port && tmp->rmt_port == hdr->src_port) |