X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=blobdiff_plain;f=src%2Fvnet%2Fudp%2Fudp.c;h=8fa1147b03050aec5274ac6b6a76b327a4c66b48;hp=1fb7a507544665fa266a2b0f67718fb78ddec2c9;hb=07063b8ea;hpb=a26349da47d9a05d9fe9725343aa85e9640ab1ea diff --git a/src/vnet/udp/udp.c b/src/vnet/udp/udp.c index 1fb7a507544..8fa1147b030 100644 --- a/src/vnet/udp/udp.c +++ b/src/vnet/udp/udp.c @@ -58,9 +58,22 @@ udp_connection_alloc (u32 thread_index) void udp_connection_free (udp_connection_t * uc) { - pool_put (udp_main.connections[uc->c_thread_index], uc); + u32 thread_index = uc->c_thread_index; if (CLIB_DEBUG) clib_memset (uc, 0xFA, sizeof (*uc)); + pool_put (udp_main.connections[thread_index], uc); +} + +void +udp_connection_delete (udp_connection_t * uc) +{ + if ((uc->flags & UDP_CONN_F_OWNS_PORT) + || !(uc->flags & UDP_CONN_F_CONNECTED)) + udp_unregister_dst_port (vlib_get_main (), + clib_net_to_host_u16 (uc->c_lcl_port), + uc->c_is_ip4); + session_transport_delete_notify (&uc->connection); + udp_connection_free (uc); } u32 @@ -73,7 +86,8 @@ udp_session_bind (u32 session_index, transport_endpoint_t * lcl) void *iface_ip; udp_dst_port_info_t *pi; - pi = udp_get_dst_port_info (um, lcl->port, lcl->is_ip4); + pi = + udp_get_dst_port_info (um, clib_net_to_host_u16 (lcl->port), lcl->is_ip4); if (pi) return -1; @@ -95,12 +109,12 @@ udp_session_bind (u32 session_index, transport_endpoint_t * lcl) listener->c_proto = TRANSPORT_PROTO_UDP; listener->c_s_index = session_index; listener->c_fib_index = lcl->fib_index; - listener->owns_port = 1; + listener->flags |= UDP_CONN_F_OWNS_PORT; clib_spinlock_init (&listener->rx_lock); node_index = lcl->is_ip4 ? udp4_input_node.index : udp6_input_node.index; udp_register_dst_port (vm, clib_net_to_host_u16 (lcl->port), node_index, - 1 /* is_ipv4 */ ); + lcl->is_ip4); return listener->c_c_index; } @@ -148,6 +162,12 @@ udp_push_header (transport_connection_t * tc, vlib_buffer_t * b) vnet_buffer (b)->sw_if_index[VLIB_TX] = uc->c_fib_index; b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED; + if (PREDICT_FALSE (uc->flags & UDP_CONN_F_CLOSING)) + { + if (!transport_max_tx_dequeue (&uc->connection)) + udp_connection_delete (uc); + } + return 0; } @@ -164,17 +184,16 @@ udp_session_get (u32 connection_index, u32 thread_index) void udp_session_close (u32 connection_index, u32 thread_index) { - vlib_main_t *vm = vlib_get_main (); udp_connection_t *uc; + uc = udp_connection_get (connection_index, thread_index); - if (uc) - { - if (uc->owns_port || !uc->is_connected) - udp_unregister_dst_port (vm, clib_net_to_host_u16 (uc->c_lcl_port), - uc->c_is_ip4); - session_transport_delete_notify (&uc->connection); - udp_connection_free (uc); - } + if (!uc) + return; + + if (!transport_max_tx_dequeue (&uc->connection)) + udp_connection_delete (uc); + else + uc->flags |= UDP_CONN_F_CLOSING; } void @@ -216,7 +235,7 @@ format_udp_connection (u8 * s, va_list * args) if (verbose) { if (verbose == 1) - s = format (s, "%-15s\n", "-"); + s = format (s, "%-15s", "-"); else s = format (s, "\n"); } @@ -239,6 +258,7 @@ u8 * format_udp_half_open_session (u8 * s, va_list * args) { u32 __clib_unused tci = va_arg (*args, u32); + u32 __clib_unused thread_index = va_arg (*args, u32); clib_warning ("BUG"); return 0; } @@ -247,23 +267,23 @@ u8 * format_udp_listener_session (u8 * s, va_list * args) { u32 tci = va_arg (*args, u32); - u32 __clib_unused verbose = va_arg (*args, u32); + u32 __clib_unused thread_index = va_arg (*args, u32); + u32 verbose = va_arg (*args, u32); udp_connection_t *uc = udp_listener_get (tci); - return format (s, "%U", format_udp_connection, uc); + return format (s, "%U", format_udp_connection, uc, verbose); } -u16 -udp_send_mss (transport_connection_t * t) -{ - /* TODO figure out MTU of output interface */ - return 1460; -} - -u32 -udp_send_space (transport_connection_t * t) +static int +udp_session_send_params (transport_connection_t * tconn, + transport_send_params_t * sp) { /* No constraint on TX window */ - return ~0; + sp->snd_space = ~0; + /* TODO figure out MTU of output interface */ + sp->snd_mss = 1460; + sp->tx_offset = 0; + sp->flags = 0; + return 0; } int @@ -306,7 +326,7 @@ udp_open_connection (transport_endpoint_cfg_t * rmt) uc->c_is_ip4 = rmt->is_ip4; uc->c_proto = TRANSPORT_PROTO_UDP; uc->c_fib_index = rmt->fib_index; - uc->owns_port = 1; + uc->flags |= UDP_CONN_F_OWNS_PORT; return uc->c_c_index; } @@ -336,12 +356,13 @@ static const transport_proto_vft_t udp_proto = { .get_half_open = udp_session_get_half_open, .close = udp_session_close, .cleanup = udp_session_cleanup, - .send_mss = udp_send_mss, - .send_space = udp_send_space, + .send_params = udp_session_send_params, .format_connection = format_udp_session, .format_half_open = format_udp_half_open_session, .format_listener = format_udp_listener_session, .transport_options = { + .name = "udp", + .short_name = "U", .tx_type = TRANSPORT_TX_DGRAM, .service_type = TRANSPORT_SERVICE_CL, }, @@ -357,9 +378,10 @@ udpc_connection_open (transport_endpoint_cfg_t * rmt) u32 thread_index = vlib_num_workers ()? 1 : vlib_get_main ()->thread_index; u32 uc_index; uc_index = udp_open_connection (rmt); + if (uc_index == (u32) ~ 0) + return -1; uc = udp_connection_get (uc_index, thread_index); - if (uc) - uc->is_connected = 1; + uc->flags |= UDP_CONN_F_CONNECTED; return uc_index; } @@ -367,11 +389,16 @@ u32 udpc_connection_listen (u32 session_index, transport_endpoint_t * lcl) { udp_connection_t *listener; - u32 li; - li = udp_session_bind (session_index, lcl); - listener = udp_listener_get (li); - listener->is_connected = 1; - return li; + u32 li_index; + li_index = udp_session_bind (session_index, lcl); + if (li_index == (u32) ~ 0) + return -1; + listener = udp_listener_get (li_index); + listener->flags |= UDP_CONN_F_CONNECTED; + /* Fake udp listener, i.e., make sure session layer adds a udp instead of + * udpc listener to the lookup table */ + ((session_endpoint_cfg_t *) lcl)->transport_proto = TRANSPORT_PROTO_UDP; + return li_index; } /* *INDENT-OFF* */ @@ -385,12 +412,13 @@ static const transport_proto_vft_t udpc_proto = { .get_half_open = udp_session_get_half_open, .close = udp_session_close, .cleanup = udp_session_cleanup, - .send_mss = udp_send_mss, - .send_space = udp_send_space, + .send_params = udp_session_send_params, .format_connection = format_udp_session, .format_half_open = format_udp_half_open_session, .format_listener = format_udp_listener_session, .transport_options = { + .name = "udpc", + .short_name = "U", .tx_type = TRANSPORT_TX_DGRAM, .service_type = TRANSPORT_SERVICE_VC, .half_open_has_fifos = 1